Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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) преподаватели сильно сокрушались по поводу прекращения выпуска и развития семейства СМ и ЕС ЭВМ. Что то как раз говорили про мантиссу, и что интел и в подметки не годится :(


 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.042 c
3-1200551154
saNat
2008-01-17 09:25
2008.06.22
Ошибка в запросе с парметром: DBQuery: Field Table_a2 not found


2-1212056258
slimer
2008-05-29 14:17
2008.06.22
Результат TQRExpr


2-1211870709
Radgar
2008-05-27 10:45
2008.06.22
Мерцание при перемещении


4-1191969539
i
2007-10-10 02:38
2008.06.22
Пайпы и виста...


2-1212001762
buzb
2008-05-28 23:09
2008.06.22
Прозрачная форма.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский