LINUX.ORG.RU

Кто-то из нас дурак. Или я или Java...


0

0

Не совсем на тему Linux Development, но подумал, что раз тут водятся Java-программеры, кто-нибудь подскажет что-нибудь умное. Теперь по существу вопроса: имеем следующий код:

float a = 0.9373f; float b = 0.0005f; System.out.println(a+b);

Я совершенно логично полагаю, что результат должен быть 0.9378, в то время как Sun JDK 1.4.2_04 считает, что результат 0.93780005. Кто из нас дурак? (кстати, выражение 0.9374f + 0.0005f Жаба корректно считает равным 0.9379).

★★

а вы распечатайте а, которое 0.9373. такое десятичное
число нельзя представить точно точно как float.

idle ★★★★★
()

Java не дурак :)
Это вообще проблема пресдтавлений таких чисел:

bash-2.05b$ python
Python 2.3.4 (#1, Jun 6 2004, 18:47:26)
[GCC 3.3.3 20040412 (Gentoo Linux 3.3.3-r5, ssp-3.3-7, pie-8.7.5.3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 10./3.
3.3333333333333335
>>>

LX ★★
()
Ответ на: комментарий от LX

Про 10/3 на Питоне - не из той оперы несколько. Я ведь ничего ни на что не делил - только складываю.

Rolex ★★
() автор топика
Ответ на: комментарий от Rolex

> Нифига.
>
> float a = 0.9373f; System.out.println(a);

3:~$ perl -e 'printf "%f\n", 0.000000001'
0.000000
3:~$ perl -e 'printf "%12.10f\n", 0.0000000001'
0.0000000001

намек ясен?

idle ★★★★★
()

Ты не понял, просто комп не может записать некоторые числа в такой форме, неважно питон это или джава, деление или сложение, ты же привык к тому, что нельзя записать число в форме "10/3". Вот и к этому придется привыкать, кстати прикол:

bash-2.05b$ python
Python 2.3.4 (#1, Jun 6 2004, 18:47:26)
[GCC 3.3.3 20040412 (Gentoo Linux 3.3.3-r5, ssp-3.3-7, pie-8.7.5.3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.9373 + 0.0005
0.93779999999999997
>>>

LX ★★
()
Ответ на: комментарий от Rolex

> Я ведь ничего ни на что не делил - только складываю

нет. вы делили. еще в процессе компиляции, когда
определяли a и b.

idle ★★★★★
()
Ответ на: комментарий от idle

Кстати, в оффтопичном C# под оффтопиком результат - 0.9378 ...

Rolex ★★
() автор топика

Не знаю жабу вообще, но может в ней можно использовать double вместо float? Тогда результат сложения будет именно 0.9378 (во всяком случае, в Си именно такой результат получается при double+double).

nobody ★★
()
Ответ на: комментарий от nobody

Java по умолчанию вроде бы считает результат операций с плавающей точкой как double, поэтому нужно делать преобразование типа после выполнения операции.
т.е. System.out.println((float)(a+b));

EraSER
()

bash-2.05b$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
0.9373 + 0.0005
.9378





anonymous
()

[josephson@host temp]$ cat test0.cpp
#include<iostream.h>
int main(){
        float a=.9373f,b=.0005f;
        cout<<a+b<<endl;
        return 0;}
[josephson@host temp]$ g++ -o test0 test0.cpp
[josephson@host temp]$ ./test0
0.9378
[josephson@host temp]$

О, как!

josephson ★★
()
Ответ на: комментарий от josephson

[josephson@host temp]$ cat test0.c
#include<stdio.h>
int main(){
        float a=.9373f,b=.0005f;
        printf("%.4f\n",a+b);
        return 0;}
[josephson@host temp]$ gcc -o test0 test0.c
[josephson@host temp]$ ./test0
0.9378
[josephson@host temp]$

josephson ★★
()
Ответ на: комментарий от josephson

[josephson@host temp]$ cat test0.c
#include<stdio.h>
int main(){
        float a=.9373f,b=.0005f;
        printf("%.16f\n",a+b);
        return 0;}
[josephson@host temp]$ gcc -o test test0.c
[josephson@host temp]$ ./test
0.9378000264405273
[josephson@host temp]$

Н-да...

josephson ★★
()
Ответ на: комментарий от Rolex

Округляй до 4-го знака ;-)

А вообще, почитай, как числа разных типов хранятся в памяти, вопрос сразу отпадет.

AngryElf ★★★★★
()
Ответ на: комментарий от josephson

Странно

public class myclass {
public myclass() {
float a=0.1001f;
float b=0.1002f;
System.out.println("result="+(float)(a+b));
}
public static void main(String[] args){
new myclass();
}
}
result=0.20030001

Если сумма превышает единицу - тогда все нормально, выводится 4 знака после запятой, если меньше - тогда вот такой вот результат

EraSER
()
Ответ на: комментарий от Rolex

tmp$ echo '
> #include <stdio.h>
> int main()
> {
> float f1 = 0.9373, f2 = 0.0005;
> double d1 = 0.9373, d2 = 0.0005;
> printf("float = %.8f, double = %.8f\n", f1 + f2, d1 + d2);
> return 0;
> }
> ' >a.c
tmp$ gcc a.c
tmp$ ./a.out
float = 0.93780003, double = 0.93780000
tmp$

Юзай double, если жаба имеет этот тип. Потому что первое слагаемое не может быть точно представлено float, как уже сказал idle. Оно в float получается не 0.9373, а 0.93730003.

nobody ★★
()

Здается мне что ты гонишь, или переработал, или куришь много ганжи, как ты можешь требовать от числа с плавоющей точкой хранения только четырех знаков после запятой.

cushe
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.