Форум: "Начинающим";
Текущий архив: 2008.06.22;
Скачать: [xml.tar.bz2];
ВнизСравнение полей 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) преподаватели сильно сокрушались по поводу прекращения выпуска и развития семейства СМ и ЕС ЭВМ. Что то как раз говорили про мантиссу, и что интел и в подметки не годится :(
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.06.22;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.044 c