Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / strictfp / 25 сообщений из 39, страница 1 из 2
21.05.2012, 09:29:16
    #37803259
hybrid
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Привет.

я новичок в джава и у меня такая проблема:

написал метод:

private strictfp double calculate(double x, double y, String oper) {
double res = 0;
if (oper.equals("+")) {
res = x + y;
} else if (oper.equals("-")) {
res = x - y;
} else if (oper.equals("*")) {
res = x * y;
} else if (oper.equals("/")) {
res = x / y;
} else if (oper.equals("=")) {
res = x;
}
return res;
}

но при некоторых вычислениях он все равно считает неправильно. Например, 1.2 * 3 = 3.59999999996

В чем может быть проблема?
...
Рейтинг: 0 / 0
21.05.2012, 09:39:33
    #37803273
rsltr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
hybrid,

Код: java
1.
DecimalFormat format = new DecimalFormat("#.##"); 
...
Рейтинг: 0 / 0
21.05.2012, 09:49:36
    #37803281
hybrid
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
rsltr, а как его использовать?
...
Рейтинг: 0 / 0
21.05.2012, 09:52:15
    #37803284
hybrid
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
я пишу калькулятор, округления делать нельзя
...
Рейтинг: 0 / 0
21.05.2012, 09:56:29
    #37803290
Nixic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Вместо Double используйте BigDecimal
Много раз уже обсуждалось и тут и в гугле.
...
Рейтинг: 0 / 0
21.05.2012, 10:07:18
    #37803305
hybrid
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Nixic, спасибо
...
Рейтинг: 0 / 0
21.05.2012, 10:55:09
    #37803398
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
hybrid,
можно для начала просто strictfp из объявления метода убрать
...
Рейтинг: 0 / 0
21.05.2012, 13:15:13
    #37803713
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
avp.mkhybrid,
можно для начала просто strictfp из объявления метода убрать
1. Как тут влияет stractfp?
2. Это убрать можно, но это не первое. Первое - разобраться с тем, как представляются десятичные числа (double) в компьютере и какие могут быть с этим проблемы.
...
Рейтинг: 0 / 0
21.05.2012, 15:33:07
    #37804099
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Leonidvavp.mkhybrid,
можно для начала просто strictfp из объявления метода убрать
1. Как тут влияет stractfp?
Как-то так.
http://cloud-cuckoo.com.ua/content/java-strictfp-metody

Leonidv2. Это убрать можно, но это не первое. Первое - разобраться с тем, как представляются десятичные числа (double) в компьютере и какие могут быть с этим проблемы.
По-моему стереть одно слово и перекомпилировать программу значительно быстрее, чем в чём-нибудь разбираться...

То, что он разберётся - как это решит его проблему?
...
Рейтинг: 0 / 0
21.05.2012, 15:51:51
    #37804170
rfq
rfq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Считает-то он правильно. Неизбежная ошибка возникает при преобразовании 1.2 в двоичный вид. Это как если бы ты пытался 1/3 представить в десятичном виде - все равно будет ошибка.
...
Рейтинг: 0 / 0
21.05.2012, 16:14:11
    #37804241
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
avp.mk,

Когда обучаешься чем либо, лучше разбираться. И да, sctrictfp здесь не причем.
...
Рейтинг: 0 / 0
21.05.2012, 16:22:18
    #37804261
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Leonidvsctrictfp
Для чего он нужен по-вашему?
...
Рейтинг: 0 / 0
21.05.2012, 21:22:56
    #37804782
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
rfqСчитает-то он правильно. Неизбежная ошибка возникает при преобразовании 1.2 в двоичный вид. Это как если бы ты пытался 1/3 представить в десятичном виде - все равно будет ошибка.
Размялся маленько. На глаз вроде правильно. Проверить нечем.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
public class JavaApp {

    public static void main(String args[]) {
        System.out.println(toBinaryString(1.5));
        System.out.println(toBinaryString(1.2));
        System.out.println(toBinaryString(1.02));
        System.out.println(toBinaryString(1.002));
        System.out.println(toBinaryString(1.0002));
        System.out.println(toBinaryString(1.00002));
        System.out.println(toBinaryString(1.000002));
        System.out.println(toBinaryString(1.0000002));
        System.out.println(toBinaryString(1.00000002));
    }
    private final static char SEPARATOR = ',';
    private final static int ДОСТАТОЧНО_ЗНАКОВ_ПОСЛЕ_ЗАПЯТОЙ = 70;

    public static String toBinaryString(double value) {
        long integerPart = (long) value;
//        double fractionalPart = (value % 1);

//      так лучше
        double fractionalPart = value - integerPart;

//        System.out.println(integerPart);
//        System.out.println(fractionalPart);

        StringBuilder sb = new StringBuilder(Long.toBinaryString(integerPart));

        if (fractionalPart > 0) {
            sb.append(SEPARATOR);

            double etl = .5;
            int cntr = 0;

            do {
                if (fractionalPart >= etl) {
                    sb.append('1');
                    fractionalPart -= etl;
                } else {
                    sb.append('0');
                }

                etl /= 2;
            } while (fractionalPart > 0 && (++cntr < ДОСТАТОЧНО_ЗНАКОВ_ПОСЛЕ_ЗАПЯТОЙ));
        }
        return sb.toString();
    }
}
...
Рейтинг: 0 / 0
21.05.2012, 23:10:34
    #37804855
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Или даже так (предидущий не работал бы с отрицатеьными величинами)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
public class JavaApp {
    public static void main (String args[]) {
        System.out.println(toBinaryString(1.2));
        System.out.println(toBinaryString(1.02));
        System.out.println(toBinaryString(1.002));
        System.out.println(toBinaryString(1.0002));
        System.out.println(toBinaryString(1.00002));
        System.out.println(toBinaryString(1.000002));
        System.out.println(toBinaryString(1.0000002));
        System.out.println(toBinaryString(1.00000002));
        System.out.println(toBinaryString(1.000000002));
        System.out.println(toBinaryString(1.0000000002));
        System.out.println(toBinaryString(1.00000000002));
        System.out.println(toBinaryString(1.000000000002));
        System.out.println(toBinaryString(1.0000000000002));
        System.out.println(toBinaryString(1.00000000000002));
        System.out.println(toBinaryString(1.000000000000002));
        System.out.println(toBinaryString(1.0000000000000002));
        System.out.println(toBinaryString(1.00000000000000002));
        System.out.println(toBinaryString(1.000000000000000002));
        System.out.println(toBinaryString(1.0000000000000000002));
        System.out.println(toBinaryString(1.00000000000000000002));
        System.out.println(toBinaryString(1.000000000000000000002));
        System.out.println(toBinaryString(1.0000000000000000000002));
        
        System.out.println(toBinaryString(-1.2));
        System.out.println(toBinaryString(-1.02));
        System.out.println(toBinaryString(-1.002));
        System.out.println(toBinaryString(-1.0002));
        System.out.println(toBinaryString(-1.00002));
        System.out.println(toBinaryString(-1.000002));
        System.out.println(toBinaryString(-1.0000002));
        System.out.println(toBinaryString(-1.00000002));
        System.out.println(toBinaryString(-1.000000002));
        System.out.println(toBinaryString(-1.0000000002));
        System.out.println(toBinaryString(-1.00000000002));
        System.out.println(toBinaryString(-1.000000000002));
        System.out.println(toBinaryString(-1.0000000000002));
        System.out.println(toBinaryString(-1.00000000000002));
        System.out.println(toBinaryString(-1.000000000000002));
        System.out.println(toBinaryString(-1.0000000000000002));
        System.out.println(toBinaryString(-1.00000000000000002));
        System.out.println(toBinaryString(-1.000000000000000002));
        System.out.println(toBinaryString(-1.0000000000000000002));
        System.out.println(toBinaryString(-1.00000000000000000002));
        System.out.println(toBinaryString(-1.000000000000000000002));
        System.out.println(toBinaryString(-1.0000000000000000000002));
    }
    private final static char SEPARATOR = ',';
    private final static int ДОСТАТОЧНО_ЗНАКОВ_ПОСЛЕ_ЗАПЯТОЙ = 700;

    public static String toBinaryString(double value) {
        StringBuilder sb;
        if (value < 0) {
            sb = new StringBuilder("-");
            value = Math.abs(value);
        } else if (value == 0) {
            return "0";
        } else {
            sb = new StringBuilder();
        }
        
        long integerPart = (long) value;
        double fractionalPart = value - integerPart;

        sb.append(Long.toBinaryString(integerPart));

        if (fractionalPart != 0) {
            sb.append(SEPARATOR);

            double etl = .5;
            int cntr = 0;

            do {
                if (fractionalPart >= etl) {
                    sb.append('1');
                    fractionalPart -= etl;
                } else {
                    sb.append('0');
                }

                etl /= 2;
            } while (fractionalPart > 0 && (++cntr < ДОСТАТОЧНО_ЗНАКОВ_ПОСЛЕ_ЗАПЯТОЙ));
        }
        return sb.toString();
    }
}
...
Рейтинг: 0 / 0
21.05.2012, 23:44:12
    #37804898
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
avp.mk,

Чем это лучше String.format("%.70f", 1.02)?

И да, вы показываете, что не понимаете обработку вещественных чисел.
...
Рейтинг: 0 / 0
22.05.2012, 10:43:38
    #37805266
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Leonidvavp.mk,
Чем это лучше String.format("%.70f", 1.02)?
К сожалению они делают разные вещи, их несколько сложно сравнивать =)

LeonidvИ да, вы показываете, что не понимаете обработку вещественных чисел.
Где это я так прокололся, что вы разгадали мой секрет?)
...
Рейтинг: 0 / 0
22.05.2012, 10:55:15
    #37805288
Leonidv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
avp.mkLeonidvavp.mk,
Чем это лучше String.format("%.70f", 1.02)?
К сожалению они делают разные вещи, их несколько сложно сравнивать =)

И что делает ваша функция.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
02.09.2013, 02:16:13
    #38383748
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Хм....

Прошу прощения за внезапный ап.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
import static java.lang.Math.PI;

public class testStrictFp{


        public strictfp static void testStrictCallback(){
                double x=1.0/PI;
                float y=(float)1.0/(float)PI;
                System.out.println("Double:"+ x);
                System.out.println("Float:"+ y);
        }

        public static void testNonStrictCallback(){
                double x=1.0/PI;
                float y=(float)1.0/(float)PI;
                System.out.println("Double:"+ x);
                System.out.println("Float:"+ y);
        }

        public static void main(String[] args) throws Exception{

                testStrictCallback();
                testNonStrictCallback();

        }


}



Double:0.3183098861837907
Float:0.31830987
Double:0.3183098861837907
Float:0.31830987
...
Рейтинг: 0 / 0
02.09.2013, 16:05:58
    #38384312
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
mayton,

Я не понял вопроса)

P.S. Тема у функций одинаковые.. Так должно быть?
...
Рейтинг: 0 / 0
02.09.2013, 16:07:46
    #38384315
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
*тела
...
Рейтинг: 0 / 0
02.09.2013, 16:24:40
    #38384345
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
Я вот и думаю. Должно или не должно.

The Java® Virtual
Machine Specification
Java SE 7 Edition 2.8.2 Floating-Point Modes
Every method has a floating-point mode, which is either FP-strict or not FPstrict.
The floating-point mode of a method is determined by the setting of the
ACC_STRICT flag of the access_flags item of the method_info structure (§4.6)
defining the method. A method for which this flag is set is FP-strict; otherwise, the
method is not FP-strict.
...
Рейтинг: 0 / 0
02.09.2013, 16:59:44
    #38384403
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
strictfp гарантирует одинаковость результатов на разных (со)процессорах.
Смысл гонять такие тесты на одном и том же сопроцессоре одного и того же интела.
Вот если у вас под руками Power и ARM - да, интересно.
...
Рейтинг: 0 / 0
02.09.2013, 17:49:02
    #38384493
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
ОК. Я понял. Я просто другой смысл узрел в документации по JVM. ну да ладно. Всем спасибо.
...
Рейтинг: 0 / 0
02.09.2013, 19:02:32
    #38384566
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
И не с float :)
...
Рейтинг: 0 / 0
02.09.2013, 20:07:06
    #38384636
avp.mk
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
strictfp
У меня не получилось смоделировать случай чтобы метод с модификатором strictfp считал не так как точно такойже метод без этого модификатора. Может в VM есть флаг который определяет ограничивать точность всех расчётов или нет? (и по умолчанию он установлен)

TestStrictFp
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
package teststrictfp;

import static java.lang.Math.PI;

public class TestStrictFp {

    public static double first(double x, double y) {
        return PI * x / y;
    }

    public static strictfp double firstStricted(double x, double y) {
        return PI * x / y;
    }

//    public static double second(double x, double y) { return PI * (x / y); }
//    public static strictfp double secondStricted(double x, double y) { return PI * (x / y); }
    
    public static void main(String[] args) throws Exception {
        double y = 1.2;

        int counter = 0;
        for (double x = 0; x < 1_000_000_000; x += 0.00000000001) {
            //<editor-fold defaultstate="collapsed" desc="noise">
            if (++counter % 2_000_000_000 == 0) {
//            if (++counter % 100_000_000 == 0) {
                System.out.printf("\t\t\t\t\t\tworks %f\n", x);
            }
            //</editor-fold>

            double //
                    first = first(x, y),
                    firstStricted = firstStricted(x, y);
//                    second = second(x, y),
//                    secondStricted = secondStricted(x, y);

            if (first != firstStricted) {
                System.out.printf("found!\n"
                        + "first           : %s\n"
                        + "first_stricted  : %s\n",
                        first, firstStricted);
                return;
            }
        }
    }
}

...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / strictfp / 25 сообщений из 39, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]