Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> oracle number -> BigDecimal, различн. значения в PlSql Dev. и java 
:(
    Опции темы
KostenkoSergey
Дата 11.9.2007, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 31.10.2005
Где: Kiev

Репутация: 3
Всего: 8



Столкнулся с такой вот проблемой :
Выполняя запрос (select mynumber from mytable)в пл\скл девелопере получаю 9.8,
а при использовании 
Код

        ResultSet result  = stat.executeQuery(" select mynumber from mytable ");
        result.next();
        BigDecimal x = result.getBigDecimal("mynumber ");


Получаю 9.799999999999999

Подскажите с чем это связано и как побороть ?
PM ICQ   Вверх
dorogoyIV
Дата 11.9.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



если побороть в смысле округлить
Код

х.setScale(1, BigDecimal.ROUND_HALF_UP);

1 - это количество знаков после запятой. второй параметр - способ округления, их несколько разных есть.
PM MAIL   Вверх
KostenkoSergey
Дата 11.9.2007, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 31.10.2005
Где: Kiev

Репутация: 3
Всего: 8



Цитата(dorogoyIV @  11.9.2007,  11:20 Найти цитируемый пост)
если побороть 

да, я думал об этом - но в таком случае если в поле нумбер будет целое число - оно допишет .0, да и заранее сколько знаков после запятой будет я не знаю.

PM ICQ   Вверх
dorogoyIV
Дата 11.9.2007, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



посмотри такой код. может пригодится?
Код

  BigDecimal x=new BigDecimal(12.3);
  BigDecimal y=new BigDecimal("12.3");

  System.out.println(x+"\n"+y);

PM MAIL   Вверх
KostenkoSergey
Дата 11.9.2007, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 290
Регистрация: 31.10.2005
Где: Kiev

Репутация: 3
Всего: 8



Цитата(dorogoyIV @  11.9.2007,  12:14 Найти цитируемый пост)
посмотри такой код. может пригодится?
 - не совсем понял, что ты хотел показать фрагментом кода.

Свой вопрос пока решил следующим образом: 
Код

...
        if (columType.equalsIgnoreCase("number")) {
          BigDecimal bd = _resultSet.getBigDecimal(i);
          if (bd != null)
            if (bd.scale() == 0) {
              // -- BD
              tmpElement.appendChild(doc.createTextNode(bd.toString()));
            } else {
              // -- Float
              tmpElement.appendChild(doc.createTextNode(Float.toString(bd.floatValue())));
            }
        }
...


ps буду надеяться размерности флоата будет достаточно.

Это сообщение отредактировал(а) KostenkoSergey - 11.9.2007, 12:35
PM ICQ   Вверх
dorogoyIV
Дата 11.9.2007, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(KostenkoSergey @  11.9.2007,  12:34 Найти цитируемый пост)
 - не совсем понял,

в учебнике у меня написано:
Цитата

В классе BigDecimal четыре конструктора: 

1.BigDecimal (Biglnteger bi) — объект будет хранить большое целое bi, порядок равен нулю; 
2.BigDecimal (Biglnteger mantissa, int scale) — задается мантиса mantissa и неотрицательный порядок    scale объекта; если порядок scale отрицателен, возникает исключительная ситуация; 
3.BigDecimal (double d) — объект будет содержать вещественное число удвоенной точности d ; если значение d бесконечно или NaN , то возникает исключительная ситуация; 
4.BigDecimal (String val) — число задается строкой символов val , которая должна содержать запись числа по правилам языка Java. 
При использовании третьего из перечисленных конструкторов возникает неприятная особенность, отмеченная в документации. Поскольку вещественное число при переводе в двоичную форму представляется, как правило, бесконечной двоичной дробью, то при создании объекта, например, BigDecimal(0.1) , мантисса, хранящаяся в объекте, окажется очень большой. Но при создании такого же объекта четвертым конструктором, BigDecimal ("0.1") , мантисса будет равна просто 1. 


PM MAIL   Вверх
niasilil
Дата 13.11.2008, 08:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.6.2007
Где: USA

Репутация: 8
Всего: 9



bump

Правлю чужой код, сравниваю баланс - фиг вам, куда то подевался цент. 
Пытаюсь найти, все вроде нормально, но цента нет. Было что то типа 89.21 стало несколько платежей но в сумме 89.20
Оказалось оно - кто то использовал BigDecimal(double) вместо BigDecimal(String). 

Вообще непонятен глубокий смыслтакого поведения конструктора с double. Ведь ясно же что баг, так нет, записали в API как feature. 


--------------------
SCJP 5.0, SCJD
PM MAIL   Вверх
w1nd
Дата 13.11.2008, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(niasilil @  13.11.2008,  08:09 Найти цитируемый пост)
Вообще непонятен глубокий смыслтакого поведения конструктора с double. Ведь ясно же что баг, так нет, записали в API как feature. 

Это не баг, это свойство double. Машинные числа с плавающей точкой нельзя использовать для точных расчётов в принципе.


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
niasilil
Дата 16.11.2008, 08:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.6.2007
Где: USA

Репутация: 8
Всего: 9



Баг это, баг. Просто его объявили фичей. 
Ничего мы тут не считаем, просто создаем объект. Можно просто в лоб заменить весь конструктор 

Код

public BigDecimal(double val) {
    ....
}


на 
Код

public BigDecimal(double val) {
    this(new Double(val).toString());
}


и все будет работать как и должно. Мне Рабинович напел что в сях такого безобразия нет, сам не проверял. 
Вот
Код

    public static void main(String[] args) {
        BigDecimal bd1 = new BigDecimal(0.1);
        BigDecimal bd2 = new BigDecimal(new Double(0.1).toString());
        System.out.println(bd1 + "\n" + bd2);
    }

выдает как и положено 
0.1000000000000000055511151231257827021181583404541015625
0.1


--------------------
SCJP 5.0, SCJD
PM MAIL   Вверх
dorogoyIV
Дата 16.11.2008, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(niasilil @  16.11.2008,  08:19 Найти цитируемый пост)
Баг это, баг

не баг это, не баг!
повторите первый курс института (высшая математика)  smile 
PM MAIL   Вверх
niasilil
Дата 17.11.2008, 03:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.6.2007
Где: USA

Репутация: 8
Всего: 9



Цитата(dorogoyIV @ 16.11.2008,  12:04)
Цитата(niasilil @  16.11.2008,  08:19 Найти цитируемый пост)
Баг это, баг

не баг это, не баг!
повторите первый курс института (высшая математика)  smile

и как же это не баг если два конструктора выдают два разных значения? просто из общих соображений. 
Код

double d = 0.1;
BigDecimal bd1 = new BigDecimal(d);
BigDecimal bd2 = new BigDecimal(d + "");

dorogoyIV, какую конкретно часть первого курса высшей математики вы имеете ввиду? я как бы немного с этим знаком, кандидат физмат наук как никак. Было бы все же полезнее аргументировать, а не так. Я не обязан вам верить на слово. 

фиг с ним, баг это или не баг. Но вот объясните мне зачем используется два разных способа создания объекта в двух разных конструкторах? Какой в этом смысл? По мне так это бред полный. 


--------------------
SCJP 5.0, SCJD
PM MAIL   Вверх
dorogoyIV
Дата 17.11.2008, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



niasilil
Цитата(dorogoyIV @  11.9.2007,  13:56 Найти цитируемый пост)
при переводе в двоичную форму

наверное с этим связано?

PM MAIL   Вверх
w1nd
Дата 17.11.2008, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 20
Всего: 54



Цитата(niasilil @  17.11.2008,  03:38 Найти цитируемый пост)
и как же это не баг если два конструктора выдают два разных значения?

Не разные способы конструкции приводят к отклонениям, а разные значения параметров. Иными словами, 0.1D - совсем не то же самое, что "0.1". Именно об этом и просил вас вспомнить dorogoyIV.


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
avvo
Дата 21.11.2008, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 11.9.2007

Репутация: нет
Всего: 4



IEEE 754

А высшая математика тут, да, не при чем. Тут только "низшая", то бишь арифметика. smile

Да и в том, что два разных конструктора создают два разных объекта, мне, как простому инженеру, кажется, ничего удивительного нет.
PM MAIL   Вверх
niasilil
Дата 21.11.2008, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 4.6.2007
Где: USA

Репутация: 8
Всего: 9



Хотел поспорить, аргументы подготовил, но все стер нафиг - разговор немого с глухим получается. 
Вы мне объясняете почему теряется точность, так это очевидно почему. И из кода конструкторов видно. Мне совсем неочевидно другое. 
Как по вашему, где может применяться конструктор new BigDecimal(double d), если сразу в API написано что результат непредсказуем? Пример бы помог меня убедить. 
Если примеров нет, то предлагаю согласиться что разумно было бы depricate этот конструктор и все тут. 


--------------------
SCJP 5.0, SCJD
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0974 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.