Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.06.22;
Скачать: CL | DM;

Вниз

Сравнение полей DOUBLE PRECISION в запросе   Найти похожие ветки 

 
grav   (2008-05-28 16:11) [0]

Есть в таблице поле типа DOUBLE PRECISION.
Все бы хорошо, но значения этих полей отображаются так:
если, например, в поле таблицы значение = 0.4, то в поле DBEdit отобразится 0.39999999898989. Это поправимо, устанавливаем в свойствах IBDataSet для данного поля Precision=5 и имеем в DBEdit 0.4.
Но вот потребовалось сравнить два таких поля в SQL. Оказалось, что нет в таблице в базе двух одинаковых значений. Что не так?


 
Reindeer Moss Eater ©   (2008-05-28 16:26) [1]

все так


 
Reindeer Moss Eater ©   (2008-05-28 16:26) [2]

Сам спросил, сам ответил.
Оказалось, что нет в таблице в базе двух одинаковых значений.


 
grav   (2008-05-28 16:36) [3]


> Reindeer Moss Eater ©   (28.05.08 16:26) [2]
> Сам спросил, сам ответил.
> Оказалось, что нет в таблице в базе двух одинаковых значений.
>

А они есть :(
Могло это быть из-за того, что данные из DBEdit вставлялись в таблицу как
ParamByName().AsString (думал IBX Сам размерется с типом данных), а не ParamByName().AsFloat?


 
Reindeer Moss Eater ©   (2008-05-28 16:38) [4]

Если бы они были, сравнение возвращало бы True


 
Prohodil Mimo ©   (2008-05-28 16:45) [5]

grav   (28.05.08 16:11)
а ты уверен, что поле именно DOUBLE PRECISION, а не Number или что-то подобное?
Я когда на IB переходил, со всеми типами такое было, но не с DOUBLE PRECISION. Если задал ему 0.4, то в базе и будет 0.4, даже при сравнении и в ХП и в SQL.
А вообще, на ibase.ru есть статья по этим типам.


 
grav   (2008-05-28 16:47) [6]


> Reindeer Moss Eater ©   (28.05.08 16:38) [4]

У меня не просто поля сравниваются. Сравниваются суммы полей с одним значением. Это контроль на правильность введенных данных.
Т.е. площадь по предприятию должна быть равна сумме площадей зданий.
Так вот они не равны, а отображаются одинаково, например 500,4


 
Reindeer Moss Eater ©   (2008-05-28 16:49) [7]

дабл прецижен испокон аеков был плавающей точкой. и таким и остается


 
Reindeer Moss Eater ©   (2008-05-28 16:50) [8]

Так вот они не равны, а отображаются одинаково, например 500,4

Верно. Они не равны.

а отображаются одинаково
И чего?


 
sniknik ©   (2008-05-28 16:50) [9]

станут ли равны 500,43 и 500,42 если отображать их только до первого знака, типа 500,4 и 500,4?


 
grav   (2008-05-28 16:57) [10]


> sniknik ©   (28.05.08 16:50) [9]

Вот пример, копирую из DBGrid:
значение поля по предприятию 14,3999996185303 (вводили 14,4)
сумма по зданиям 14,3999999761581
Почему 14,4 стало 14,3999996185303?


 
grav   (2008-05-28 17:00) [11]


> Prohodil Mimo ©   (28.05.08 16:45) [5]
> а ты уверен, что поле именно DOUBLE PRECISION, а не Number
> или что-то подобное?

Уверен, изначально задавал. Но значение Precision не указывал для полей в IBDataSet, может надо было ограничить.


 
Reindeer Moss Eater ©   (2008-05-28 17:04) [12]

Вот пример, копирую из DBGrid:
значение поля по предприятию 14,3999996185303 (вводили 14,4)
сумма по зданиям 14,3999999761581
Почему 14,4 стало 14,3999996185303?


Потому что тип с плавающей точкой.


 
sniknik ©   (2008-05-28 17:07) [13]

> Почему 14,4 стало 14,3999996185303?
таково свойство чисел с плавающей запятой, если коротко. подробнее ищи статью на королевстве, так и называется вроде "особенности чисел с плавающей запятой"


 
grav   (2008-05-28 17:08) [14]


> Reindeer Moss Eater ©   (28.05.08 17:04) [12]

А надо было чего, чтобы хранить вещественные числа типа 14,4?

Нет, все же виновата моя лень, надо было писать сразу ParamByName().AsFloat. Сейчас вроде нормально сохраняется и суммируется. А старые данные поправим :)
Или все же в другом проблема?


 
Reindeer Moss Eater ©   (2008-05-28 17:19) [15]

читай Data Definition Guide.
раздел "Defining numeric data types"


 
sniknik ©   (2008-05-28 17:20) [16]

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374


 
Prohodil Mimo ©   (2008-05-28 17:52) [17]

grav   (28.05.08 17:00) [11]
Уверен, изначально задавал. Но значение Precision не указывал для полей в IBDataSet, может надо было ограничить


не знаю что это такое, и не использовал никогда и работаю с FIBPlus. Но вот 14,3999996185303 не видел ни разу на DOUBLE PRECISION


 
Правильный_Вася   (2008-05-28 19:02) [18]

используй типы даных с фиксированной точкой


 
Правильный_Вася   (2008-05-28 19:03) [19]

а сравнивать числа с плавающей точкой можно с учетом погрешности, например,
abs(a-b)<0.00001


 
MsGuns ©   (2008-05-28 22:35) [20]

1. Не использовать в критичных для выборок и ОСОБЕННО для связок полях тип с плавающей точкой.
2. При использовании таких поле в условиях выборки применять к ним "приводящие" операции типа округления или порядка дроби


 
grav   (2008-05-29 10:02) [21]


> MsGuns ©   (28.05.08 22:35) [20]

Какой же тип использовать? NUMERIC?


 
grav   (2008-05-29 10:10) [22]


> Правильный_Вася   (28.05.08 19:03) [19]

В SQL есть этот ABS?


 
Reindeer Moss Eater ©   (2008-05-29 10:14) [23]

А может доки почитаем?


 
grav   (2008-05-29 11:28) [24]


> Reindeer Moss Eater ©   (29.05.08 10:14) [23]
> А может доки почитаем?

Обязательно почитаем. И уже читаю

> sniknik ©   (28.05.08 17:20) [16]
> http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374

Очень интерессная статья, спасибо за ссылку.
Но там про вещественные типы данных Delphi. Еще бы надо про вещественные  типы данных FireBird.
14,3999996185303 это делфи так берет, или в базе так хранятся?


 
sniknik ©   (2008-05-29 11:35) [25]

> Но там про вещественные типы данных Delphi. Еще бы надо про вещественные  типы данных FireBird.
без разницы, это "машинные" типы, а не "языковые". ты статью то читал? там это понятно расписано.


 
grav   (2008-05-29 11:50) [26]


> sniknik ©   (29.05.08 11:35) [25]

Еще раз спасибо за статью. Я в шоке!

var R:Single;
begin
 R:=0.1;
 if R=0.1 then
  Label1.Caption:="Равно"

 else
  Label1.Caption:="Не равно"
end;

Не равно! А ведь и правда число 0.1 не представимо в виде конечной двоичной дроби.


 
Reindeer Moss Eater ©   (2008-05-29 11:52) [27]

децимал или нумерик + третий диалект.


 
grav   (2008-05-29 12:09) [28]


> Reindeer Moss Eater ©   (29.05.08 11:52) [27]
> децимал или нумерик + третий диалект.

Мне уже не поменять структуру, там уже десятки тысяч записей.
Да и ParamByName().AsFloat  вроде бы помогло, по крайней мере 0.1 из базы обратно так и считывается как 0.1. И в сравнении они равны.
Из чего делаю вывод, что вставка в поле базы данных типа Double как ParamByName().AsString обрезает числа до типа Single.


 
Ослик   (2008-05-29 12:16) [29]

[28] grav   (29.05.08 12:09)
> Мне уже не поменять структуру, там уже десятки тысяч записей.

Да Хоть десять тысяч мульенов. В чем проблема-то?
Вариантов несколько, например делаешь таблицу такую-же таблицу но с другим именем, туда все переливаешь из исходной, дропаешь исходную и создаешь ее уже с правильным полем, переливаешь в нее записи из копии.


 
Reindeer Moss Eater ©   (2008-05-29 12:18) [30]

Мне уже не поменять структуру, там уже десятки тысяч записей.

Хоть миллионы. Не вижу препятствий.

property TParam.AsFloat: Double;

А это тоже плавающая точка.


 
grav   (2008-05-29 12:28) [31]


> Reindeer Moss Eater ©   (29.05.08 12:18) [30]

> property TParam.AsFloat: Double;
>
> А это тоже плавающая точка.

Это и хорошо. Так поля в базе и вставляемые переменные совпадают, поэтому 0.1 так и останется 0.1, а не 0.100000001490116


 
Правильный_Вася   (2008-05-29 12:29) [32]


> В SQL есть этот ABS?

подключаем UDF из комплекта поставки (в справке написано как) и радуемся


 
Reindeer Moss Eater ©   (2008-05-29 12:29) [33]

А говорил читал статью


 
grav   (2008-05-29 12:32) [34]


> Ослик   (29.05.08 12:16) [29]

6 операторов с 8 до 17 часов заколачивают в базу данные. Еще 2 ведут контроль на правильность забивки. Никто не даст остановить работу.
Файл программы мне еще удается менять, как только кто то из операторов захочет чайку :)


 
Правильный_Вася   (2008-05-29 12:36) [35]


> 6 операторов с 8 до 17 часов заколачивают в базу данные
>  Никто не даст остановить работу.

у тебя в 2 раза больше времени, чем у них - с 17 до 8


 
Reindeer Moss Eater ©   (2008-05-29 12:36) [36]

сравнивай разность значений с допустмо малой величиной.


 
grav   (2008-05-29 12:37) [37]


> Reindeer Moss Eater ©   (29.05.08 12:29) [33]
> А говорил читал статью

А чего не так то?
Я понял, что ни 0.1, ни мои 0.4 (или 13.4) в базу записать точно нельзя. Точно также как и достать из базы. Но если записаны в базу double, то и считаны будут double.
Одно плохо, что мне надо сравнить например, 0.5 записанное в базу и SUM(0.4+0.1). Боюсь, что равенства не будет, а потому ABS  мне поможет (наверное)


 
Ослик   (2008-05-29 12:37) [38]

[34] grav   (29.05.08 12:32)
На тестовой базе пишется и отлаживается скрипт.
Затем в конце рабочего дня после стандартного ежедневного бакапа базы он запускается и на твоих мизерных данных отрабатывает в течении 0.004 секунды.


 
Reindeer Moss Eater ©   (2008-05-29 12:39) [39]

А чего не так то?

То что сравнивать плавающую точку на равенство в той статье не рекомендуют.


 
grav   (2008-05-29 12:52) [40]


> Reindeer Moss Eater ©   (29.05.08 12:39) [39]
>
> То что сравнивать плавающую точку на равенство в той статье
> не рекомендуют.

С этим согласен.
У меня вообще мироощущение поменялось с сегодняшнего дня. Я теперь компьютерам и калькуляторам не доверяю.
Помнится во времена учебы моей (1993-1999) преподаватели сильно сокрушались по поводу прекращения выпуска и развития семейства СМ и ЕС ЭВМ. Что то как раз говорили про мантиссу, и что интел и в подметки не годится :(


 
grav   (2008-05-29 13:05) [41]


> Ослик   (29.05.08 12:37) [38]

Я и не спорю, но пока обойдусь ABS в запросе.
В основном из-за того, что не понимаю тип NUMERIC. Хотя использую его для больших значений состоящих из целых чисел.


 
Ослик   (2008-05-29 13:12) [42]

[41] grav   (29.05.08 13:05)
для понимания полезно документацию читать.

нумерик хранит все ввиде целочисленого значения.
например, нумерик(10,3) число 134.56 будет хранить как 134560.
по-крайней мере это справедливо для третьего диалекта ИБ.


 
MsGuns ©   (2008-05-29 14:19) [43]

NUMERIC, DECIMAL и т.д. служат лишь УКАЗАНИЕМ серверу для ОКРУГЛЕНИЯ УКАЗАННОГО КОЛ-ВА РАЗРЯДОВ при подготовке данных, ХРАНЯЩИХСЯ КАК ЧИСЛО С ПЛАВАЮЩЕЙ ТОЧКОЙ, к отправке клиенту - как они будут обрабатываться на клиенте (округляться, сравниваться, умножаться и т.д. - ему серобуромалиново).

Прежде чем "менять мироощущение", может, стоило бы почитать что-нибудь ? Пока "операторы неустанно  вбивают".


 
Reindeer Moss Eater ©   (2008-05-29 14:38) [44]

ХРАНЯЩИХСЯ КАК ЧИСЛО С ПЛАВАЮЩЕЙ ТОЧКОЙ

разве?


 
Johnmen ©   (2008-05-29 16:11) [45]


> MsGuns ©   (29.05.08 14:19) [43]

Для IB/FB при определенных значениях NUMERIC и DECIMAL это не так.


 
Reindeer Moss Eater ©   (2008-05-29 16:30) [46]

http://img143.imageshack.us/img143/863/numericdtyl8.jpg


 
MsGuns ©   (2008-05-29 16:39) [47]

>Johnmen ©   (29.05.08 16:11) [45]
>Для IB/FB при определенных значениях NUMERIC и DECIMAL это не так.

Вполне может быть - слишком давно не работал с ИБ
Но дело, в общем, не в этом. Такой подход, ИМХО, весьма полезен СУБД-разработчику при проектировании как бизнес-логики сервера, так и прикладных решений. Дабы не заморачиваться проблемами, подобными сабжевой.


 
Anatoly Podgoretsky ©   (2008-05-29 16:58) [48]

> grav  (28.05.2008 16:57:10)  [10]

.4 не возможно представить в формате с плавающей запятой.


 
Anatoly Podgoretsky ©   (2008-05-29 17:00) [49]

> grav  (29.05.2008 12:28:31)  [31]

0.1 тоже нельзя представить


 
grav   (2008-05-29 22:20) [50]


> Anatoly Podgoretsky ©   (29.05.08 17:00) [49]

Я про это и написал.
FloatToStr даст 0.1 из 0.100000001490116


 
grav   (2008-05-29 22:28) [51]

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


 
Johnmen ©   (2008-05-29 22:31) [52]

Может пора-таки документацию почитать?



Страницы: 1 2 вся ветка

Текущий архив: 2008.06.22;
Скачать: CL | DM;

Наверх




Память: 0.6 MB
Время: 0.089 c
15-1210102201
Маэстро
2008-05-06 23:30
2008.06.22
Программисты вопрос!!!!!


2-1211988642
Smile
2008-05-28 19:30
2008.06.22
Отменить Font.Style


2-1211471462
незнайка
2008-05-22 19:51
2008.06.22
QuantumGrid и значение ячейки


2-1211854505
AlekseyB
2008-05-27 06:15
2008.06.22
DBGRID


15-1210277107
AlexDan
2008-05-09 00:05
2008.06.22
Графический файл на фотоаппарат.