powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Сравнение чисел double
25 сообщений из 43, страница 1 из 2
Сравнение чисел double
    #37453847
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
n1 = 10000.00
n2 = 21832.60-11832.60

? n1-n2

Результат - 0.00

? (n1-n2)*10000000000

Результат - 0.02
Т.е, в первом сравнении результат тоже не 0, а просто округлен до 2-х знаков
Логично было бы в этом случае, чтобы результат выражения

? (n1-n2)==0.00

был .F.

но он .T.

В связи с этим возникает вопрос. Как выполняется сравнение numeric, внутренний формат которых double ?
Это не точное сравнение, а сравнение с учетом некоторой погрешности ?
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37453913
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фокс хранит нумерик переменные как восьмибайтное двоичное с плавающей запятой.

В хэлпе на фокс заявлена 16-тизначная точность и есть пометка что реально 15,95 знаков, т.е. не все 16-тизначные точно покажутся, у некоторых возможно изменение на 1 младшего разряда.
Это связано с погрешностями преобразования десятичных чисел в восьмибайтное двоичное с плавающей запятой. И касается не только фокса, а всех прог использующих такой тип при расчетах.

Твой пример у меня нормально отрабатывает
Код: plaintext
1.
2.
3.
4.
5.
6.
n1 =  10000 . 00 
n2 =  21832 . 60 - 11832 . 60 

r = n1-n2
? r &&  0 . 0000 
? r ==  0 . 00  && .T.
? r* 10000000000  &&  0 . 0182 

Рекомендую почаще делать округление при расчетах
Код: plaintext
1.
2.
3.
r = round(n1-n2,  2 )
? r &&  0 . 00 
? r ==  0 . 00  && .T.
? r* 10000000000  &&  0 . 00 
или использовать тип CURRENCY для денежных расчетов, правда у него свои подводные камни есть.
Код: plaintext
1.
2.
3.
4.
5.
6.
n1 = $ 10000 . 00 
n2 = $ 21832 . 60 -$ 11832 . 60 

r = n1-n2
? r  &&  0 . 0000 
? r ==  0 . 00   && .T.
? r* 10000000000  &&  0 . 0000 
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37453936
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу особенностей операций с 8-ми байтными double я в курсе, что результат операции может быть не 0, а какое-то очень малое значение. И по поводу типа Currency тоже.
Вопрос заключается не в этом.
В приведенном примере как раз возникает такой случай, и сравнение двух значений должно давать .F.. Но оно дает .T.
Почему ? Как фокс сравнивает 2 числа double ? С учетом какой-то погрешности, так получается ?
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37453967
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Код: plaintext
1.
2.
3.
4.
5.
6.
n1 =  10000 . 00 
n2 =  21832 . 60 - 11832 . 60 

r = n1-n2
? r &&  0 . 0000 
? r ==  0 . 00  && .T.
? r* 10000000000  &&  0 . 0182 
[/src]

Я уточню

Исходя из того, что

? r*10000000000 && 0.0182

получается, что r не ноль, и сравнение с нулем должно давать .F.
Если написать этот код на C, то так и получится
Но фокс при сравнении с нулем дает .T.
Значит, у фокса алгоритм сравнения не просто сравнение двух значений, а какой-то другой
Меня интересует, какой
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37454369
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavel09Dima T
Код: plaintext
1.
2.
3.
4.
5.
6.
n1 =  10000 . 00 
n2 =  21832 . 60 - 11832 . 60 

r = n1-n2
? r &&  0 . 0000 
? r ==  0 . 00  && .T.
? r* 10000000000  &&  0 . 0182 
[/src]

Я уточню

Исходя из того, что

? r*10000000000 && 0.0182

получается, что r не ноль, и сравнение с нулем должно давать .F.
Если написать этот код на C, то так и получится
Но фокс при сравнении с нулем дает .T.
Значит, у фокса алгоритм сравнения не просто сравнение двух значений, а какой-то другой
Меня интересует, какой

а как насчет поставить перед всем этим
SET DECIMALS TO 18
и "конкретизировать четкость сравнения"?
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37454425
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SSn888а как насчет поставить перед всем этим
SET DECIMALS TO 18
и "конкретизировать четкость сравнения"?

Я, собственно, не фокспрошник, и пришел на этот форум из

http://clipper.borda.ru/?1-4-0-00000596-000-0-0-1316771302

где обсуждается такой же вопрос. Меня заинтересовало, как фокс сравнивает double так, что игнорируются ошибки округления.
Что такое set decimals, я конечно знаю. Эта настройка определяет количество десятичных знаков для отображения, но никак не для сравнения. В фоксе, насколько я понимаю, неявно она используется и для алгоритма сравнения.

Но даже в msdn об этом ничего не сказано:

http://msdn.microsoft.com/en-us/library/azeb8csc(VS.80).aspx

Причем, если изменить set decimals после выполнения сравнения, то новая настройка на последющие операции сравнения не повлияет.

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

В любом случае, спасибо за ответы.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37454547
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот здесь http://forum.foxclub.ru/read.php?29,401694,page=5 почитайте ответ Igor Korolyov Дата: 08.09.09 17:04:09

Igor KorolyovСпособ описания числового литерала в исходном коде влияет как на собственно "значение", так и на эти служебные поля - поэтому и существует разница между написанием ln1 = 2.05 и ln1 = 2.05000000
(...)
Как видно из примера - фокс пытается кое где применить "человеческую" логику и таки провести неявное округление для целей сравнения (и не только сравнения, кстати)

Про структуру хранения в оперативной памяти есть только со времен FoxPro for DOS. Более свежей документации нет. Например, можно посмотреть здесь http://forum.foxclub.ru/read.php?29,378070,page=2
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37455418
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Pavel09]SSn888....
Свой вопрос я собственно задал для того, чтобы, возможно, в харборе использовать алгоритм сравнения фокса. Перенять, так сказать, передовой опыт....
Явно это нигде не описано, но фокс кроме значения похоже хранит точность: количество десятичных знаков после запятой (возможно количество десятичных разрядов).
И точность результата определяется точностью операндов и операцией. Например при сложении берется максимальная точность, при умножении - произведение точностей и т.д.
Сравнение похоже идет с учетом точности сравниваемых значений.
Код: plaintext
1.
2.
3.
4.
5.
6.
n1 =  12 . 0 
n2 =  13 . 45 

? n1 + n2 &&  25 . 45 
? n1 * n2 &&  161 . 400 
r = round(n1 * n2,  1 )
? r &&  161 . 4 
PS Почаще ROUND() надо использовать и тогда не будет проблем со сравнениями.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37456587
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИ точность результата определяется точностью операндов и операцией. Например при сложении берется максимальная точность, при умножении - произведение точностей и т.д.
гы...
при делении аналогично
а при вычитании точность соответственно - залезает в минуса :(

максимально возможная точность, если не указана явно - определяется исходя из минимальной чисел в выражении, _отталкиваясь_от_типа_данных_

логическая ошибка была в самом начале на уровне "Как выполняется сравнение numeric, внутренний формат которых double"
и предположения, что присваивание
n1 = 10000.00
n2 = 21832.60-11832.60
дает doble этим переменным

то есть - при отсутствии предварительного декларирования переменных указании фокс сам решает, какой тип ей назначить, когда ей дается значение... по умолчанию - в нашем примере он назначает ей вовсе ну double, а обычное число с плавающей точкой, точность которого - не больше двух десятков
если хотите честно работать именно с double (точность, если не изменяет памать - больше 3 сотен - укажите это сперва перед вашим примером
LOCAL n1 as doub,;
n2 as doub
и "будет Вам щастье"

PS:
вот выдержка из доки:
"When storing floating-point numbers in Numeric fields, numeric precision is limited to approximately 15 digits in Visual FoxPro
...
This limitation is based on the way Pentium-based processors calculate and store floating-point numbers and follows the Institute of Electrical and Electronics Engineers (IEEE) floating-point specification for manipulating floating-point numbers in binary format. This standard makes it possible for floating-point numbers to be stored in reasonable amount of space and for performing calculations more quickly.
...
For values requiring higher precision, see Double Field Type."
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37456588
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888,

не совсем закончил

ROUND тут не просто не "надо почаще", а "стоит пореже", чтоб не ввести себя самого нечаянно в заблуждение насчет надежности результата (если она определяется только автоприсвоенным типом данных и нашим ROUND)
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37456659
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888Dima TИ точность результата определяется точностью операндов и операцией. Например при сложении берется максимальная точность, при умножении - произведение точностей и т.д.
гы...
при делении аналогично
а при вычитании точность соответственно - залезает в минуса :(
гыгы вычитание = сложение с отрицательным числом. арифметика 3-4 класс.

SSn888максимально возможная точность, если не указана явно - определяется исходя из минимальной чисел в выражении, _отталкиваясь_от_типа_данных_
В фоксе нет явных числовых типов данных (как в Си например), все числа хранятся в своем double с точностью, за исключением CURRENCY.
В любом случае тип задается в момент присвоения значения, а не в LOCAL\PRIVATE\PUBLIC.


SSn888...
если хотите честно работать именно с double (точность, если не изменяет памать - больше 3 сотен - укажите это сперва перед вашим примером
LOCAL n1 as doub,;
n2 as doub
и "будет Вам щастье"
Так с ним самым фокс и работает. double - 8-байтное двоичное число с плавающей запятой. Точность те самые 15,95 знаков. Возможные значения +/-4.9E-324 to +/-8.9E307
"LOCAL n1 as doub" не делает переменную типа double, все что после "AS" используется при подсказках IntelliSense, а при исполнении игнорируется. Выполни:
Код: plaintext
1.
local x as doub
? vartype(x) 
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37456668
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888SSn888,

не совсем закончил

ROUND тут не просто не "надо почаще", а "стоит пореже", чтоб не ввести себя самого нечаянно в заблуждение насчет надежности результата (если она определяется только автоприсвоенным типом данных и нашим ROUND)
ROUND() надо там где он должен быть по логике задачи. Я это четко усвоил после войны с главбухом когда по одним и тем же расчетным данным итого не сошлось на копейку в разных отчетах, в обоих печаталось одинаково с точностью до копеек, а при расчете "итого" округлялось только в одном.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457219
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

про вычитание я вроде как прикололся... или забыл смайл поставить? :)

"В фоксе нет явных числовых типов данных" - ссылку на msdn дать или сами найдете? :)

"все числа хранятся в своем double с точностью"... ого! значит - я зря привел пример из _официальной_документации_? Вруть все разработчики? %) )

"В любом случае тип задается в момент присвоения значения, а не в LOCAL\PRIVATE\PUBLIC."... Дима... очень не люблю как-то резко говорить людям... но тут... ОКРОПИТЕ ЕГО КТО-НИТЬ СВЯТОЙ ВОДОЙ, ДАБЫ ИЗГНАТЬ СЕГО БЕСА! РТФМ!

local x as doub декларирует, что "в эту переменную будут занесены данные такого типа"... если данные НЕ занесены - какие вопросы?
Работа идет по принципу коробок
Если я говорю "Приготовь для этого самаю большую коробку" - фокс ее подготавливает и ждет что я запихаю
Если же не говорю, а просто предлагаю ему "загнать куда-нить вот это" - он просто берет наименьшую коробку из того, что может подойти, бо "нефиг колхозное добро транжирить"
И еще вот интересно - а для чего, следуя Вашей логике тогда разработчики вообще приделали это "AS " после декларирования переменной, если Вы утверждаете, что "оно ничего и не значит"? Так, чтоб поразвлекаться, наблюдая, как люди это в форуме обсуждают? ;):)

"Выполнит
local x as doub
? vartype(x)".
ну тут вооще... а как насчет доку почитать?!
цицирую хелп для vartype:
"Return value / Data type
N / Numeric, Float, Double, or Integer"
Что Вы хотели доказать своим примером?
Что фокс этой функцией возвращает N для любого из 4-х типов?
вартайп не даст Вам проверить, что у Вас - Float или вообще просто Int
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457225
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TSSn888SSn888,

не совсем закончил

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

без обид
но усваивать надо в результате обучения, чтения документации и так далее, а не как итог боевой операции.
как я уже говорил - чтоб не ввести нечаянно самого себя в заблуждение.
то, что Вы решили эту проблему роундом - вовсе не говорит, что это был единственный, и главное - наилучший вариант
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457367
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888"все числа хранятся в своем double с точностью"... ого! значит - я зря привел пример из _официальной_документации_? Вруть все разработчики? %) )
Почему врут? недоговаривают :) Ссылку давай, переведу корректно.

SSn888"Выполнит
local x as doub
? vartype(x)".
ну тут вооще... а как насчет доку почитать?!
цицирую хелп для vartype:
"Return value / Data type
N / Numeric, Float, Double, or Integer"
Что Вы хотели доказать своим примером?
Запустить религия не позволила? vartype(x) вернет тип LOGICAL т.к. всем переменным объявленным в LOCAL присваивается .F., потому что написанное после AS игнорируется при выполнении.

Numeric, Float, Double, or Integer имеют значение когда это в DBF сохраняется, т.к. там под хранение отводится конкретное количество байт и каждый из типов имеет свои ограничения и размеры. Тут разработчик решает какой тип меньше места в файле займет в зависимости от решаемой задачи.

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

Вот почитай про DOUBLE этот тип придуман Интелом и зашит в математический сопроцессор еще со времен 286 процессоров, поэтому все языки его используют одинаково.
При этом есть проблема преобразования дробных чисел из двоичного в десятичный формат - оно редко преобразовывается точно, почти всегда возникает хвост из кучи девяток или нулей с единичкой, поэтому в фоксе это полечили дополнительным ограничением точности (округлением) при выводе. При расчетах этот хвост не мешает, т.к. дает погрешность не влияющую на результат.

PS я к тому что DOUBLE бесполезно указывать т.к. оно и так используется изначально, и точность у него 15,95 десятичных знаков (2^52), никак не около трехсот. Точнее чем с DOUBLE фокс не может расчеты вести. За исключением CURRENCY где при определенном изврате можно получить 18 точных десятичных знаков.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457401
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888И еще вот интересно - а для чего, следуя Вашей логике тогда разработчики вообще приделали это "AS " после декларирования переменной, если Вы утверждаете, что "оно ничего и не значит"?
Я ж написал, для выдачи подсказок IntelliSense. Появилось это только в 7 или 8 фоксе.
Можно написать
Код: plaintext
1.
local x as Timer
x.
когда поставишь точку выйдет подсказка со всеми свойствами и методами класса TextBox. Но чтобы ты не написал после точки этот код будет нерабочим, т.к. чтобы переменная Х стала объектом класса Timer надо явно писать
Код: plaintext
X = NewObject('Timer')
и только потом пользовать его свойства и методы.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457440
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мдя
разговор вырождается в бодание...
оно мне надо?
ладно, ещ ответ

Dima TSSn888"все числа хранятся в своем double с точностью"... ого! значит - я зря привел пример из _официальной_документации_? Вруть все разработчики? %) )
Почему врут? недоговаривают :) Ссылку давай, переведу корректно.

гм... неужели народ разучился по сайтам поддержки лазать?
http://msdn.microsoft.com/en-us/library/Aa977951.aspx

Specifies the data type on which this variable or array is based.

Dima TЗапустить религия не позволила? vartype(x) вернет тип LOGICAL т.к. всем переменным объявленным в LOCAL присваивается .F., потому что написанное после AS игнорируется при выполнении.
Если человек в качестве аргумента приводит тот факт, что переменная, которой не дали явно значение - будет булевская...
мне нечего сказть... продолжайте в том же духе
"ушла весна, настало лето - спасибо партии за это"

Про тип я читал, переживать не стоит :)

Dima TPS я к тому что DOUBLE бесполезно указывать т.к. оно и так используется изначально, и точность у него 15,95 десятичных знаков (2^52), никак не около трехсот. Точнее чем с DOUBLE фокс не может расчеты вести. За исключением CURRENCY где при определенном изврате можно получить 18 точных десятичных знаков.

Я все-таки хотел бы услышать иной вариант эээ... квалифицированного перевода фразы "Specifies the data type on which this variable or array is based.", где бы объяснялось (1) почему AS фигня и (2) зачем тогда ее разработчики засунули...
Не надо уводить разговор в скользкую канаву - конкретно (цицирую) "потому что написанное после AS игнорируется при выполнении"...
Впрочем - я не удивлюсь если следующий аргумент будет "OF ClassLib тоже игнорируется, попробуй - получищь федю"

еще раз - по умолчанию, если нет явных объяв - фокс выделяет наиболее экономный вариант
число 8.4546 никогда не встанет "само" double, потому что просто Num для него выгодней
можно еще больше утрировать пример, дать значение "8" без точек и потом долго рассуждать, что "DOUBLE бесполезно указывать т.к. оно и так используется изначально"
жуть
"DOUBLE бесполезно указывать т.к. оно и так используется изначально".... "мы позвонили в такси и вызвали машину. - так вы же переезжаете, вы им сказали, что грузовик нужен? - это бесполезно и бессмысленно указывать потому что (1) диспетчера все равно при обработке игнорируют такие слова и (2) все равно система так построена что они по умолчанию при каждом вызове Камаз присылают"
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457442
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что касается хэлпа то там очень мутно написали How to: Implement Strong Typing for Class, Object, and Variable Code
Вроде как есть строгая типизация и тут же что ее нет:
"... Note: Visual FoxPro is not a strongly typed language and does not require that you declare variables with a specific data types. Visual FoxPro does not enforce strong typing at design time or run time...."
Тут перевод
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457450
SSn888
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

человек, который даже после намеков действительно всеръез полагает, что я не могу перевести столь простую фразу - мне не интересен и пахнет снобизном, а не диалогом...
желаю удачи, я самоустраняюсь от этого
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457465
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888гм... неужели народ разучился по сайтам поддержки лазать?
http://msdn.microsoft.com/en-us/library/Aa977951.aspx

Specifies the data type on which this variable or array is based.
там же ниже:
Variables and arrays created with LOCAL are initialized to false (.F.)

SSn888Dima TЗапустить религия не позволила? vartype(x) вернет тип LOGICAL т.к. всем переменным объявленным в LOCAL присваивается .F., потому что написанное после AS игнорируется при выполнении.
Если человек в качестве аргумента приводит тот факт, что переменная, которой не дали явно значение - будет булевская... мне нечего сказть... продолжайте в том же духе
Хватит говорить, скопипасти и запусти.

Лично я соглашусь что я не прав, сто раз извинюсь, проставлюсь пивом/водкой/коньяком если меня кто-нибудь научит как в фоксе явно задать тип переменной и чтоб фокс давал ошибку при присвоении переменной значения другого типа.
Достаточно простого примера типа:
Код: plaintext
1.
local x as double
x = 'qwe' && тут сообщение об ошибке.

Не типизированный язык VFP чего бы в хэлпе ни писали.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457552
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SSn888Dima TИ точность результата определяется точностью операндов и операцией. Например при сложении берется максимальная точность, при умножении - произведение точностей и т.д.
гы...
при делении аналогично
а при вычитании точность соответственно - залезает в минуса :(

максимально возможная точность, если не указана явно - определяется исходя из минимальной чисел в выражении, _отталкиваясь_от_типа_данных_

логическая ошибка была в самом начале на уровне "Как выполняется сравнение numeric, внутренний формат которых double"
и предположения, что присваивание
n1 = 10000.00
n2 = 21832.60-11832.60
дает doble этим переменным

то есть - при отсутствии предварительного декларирования переменных указании фокс сам решает, какой тип ей назначить, когда ей дается значение... по умолчанию - в нашем примере он назначает ей вовсе ну double, а обычное число с плавающей точкой, точность которого - не больше двух десятков
если хотите честно работать именно с double (точность, если не изменяет памать - больше 3 сотен - укажите это сперва перед вашим примером
LOCAL n1 as doub,;
n2 as doub
и "будет Вам щастье"

PS:
вот выдержка из доки:
"When storing floating-point numbers in Numeric fields, numeric precision is limited to approximately 15 digits in Visual FoxPro
...
This limitation is based on the way Pentium-based processors calculate and store floating-point numbers and follows the Institute of Electrical and Electronics Engineers (IEEE) floating-point specification for manipulating floating-point numbers in binary format. This standard makes it possible for floating-point numbers to be stored in reasonable amount of space and for performing calculations more quickly.
...
For values requiring higher precision, see Double Field Type."

Имеется в виду iee 754 одинарной точности aka float, что ли ? Нет, даже с 8-ми байтным double результат упомянутого выражения будет не ноль, а что-то вроде 2**-39
Если сделать простенький тест:

Local n1 = 10000.00
Local n2, n3, i
Local i1 = 0
Local i2 = 0
for i = 1 to 10000000
n2 = Round(n1+i*0.01, 2)
n3 = Round(n1+n1+i*0.01, 2)
if n1-(n3-n2)*10000000000 = 0.00
i1 ++
else
i2 ++
endif
next
? i1, i2

То видно, что где-то примерно в 13% случаев (для double, не для float) возникает погрешность.
Подобная этой програмка на С, если в ней прямо указать тип double, даст тот же результат.
И никакая заявленная точность в 16 разрядов не работает.
Вот такая она, арифметика чисел с плавающей точкой.
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457576
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SSn888еще раз - по умолчанию, если нет явных объяв - фокс выделяет наиболее экономный вариант
число 8.4546 никогда не встанет "само" double, потому что просто Num для него выгодней
Экономный для чего? Чего экономим? Повторяю числовые типы для экономии места в DBF, поэтому с точки зрения переменных от такой экономии ни жарко ни холодно. Переменных в фоксе м.б. максимум 65535 поэтому не принципиально займут их значения 1 байт или 8.

Переменным важнее экономия времени, т.е. производительность при расчетах. С этой точки зрения тип DOUBLE оптимален т.к. с ним процессор выполняет математические операции без каких либо предварительных преобразований.
Заводить кучу типов переменных для хранения чисел тоже плохо, т.к. при расчетах необходимо будет делать приведение типов, на что надо время.
К сожалению этот момент никак разработчиками не объясняется, как косвенный аргумент могу привести то что vartype() возвращает "N" для "Numeric, Float, Double, or Integer", т.е. все эти типы физически одинаково сохраняются в переменную при считывании из DBF, иначе зачем разработчикам объединять разные типы? CURENCY они ведь сюда не вставили, потому что он по другому физически хранится в переменной. Это восьмибайтное целое.
SSn888Dima T,

человек, который даже после намеков действительно всеръез полагает, что я не могу перевести столь простую фразу - мне не интересен и пахнет снобизном, а не диалогом...
желаю удачи, я самоустраняюсь от этого
Извини если чем обидел, не знаю как давно ты с фоксом работаешь (был опыт работы с VFP6 и ранее?), но предмет нашего спора это не изначально заложенный функционал, а сбоку прилепленный костыль с подачи маркетологов, прилепленный с целью прикрутить к фоксу подсказки при наборе кода в IDE, которые были в других языках на момент выхода VFP7
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457611
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavel09, ерунда какая-то у тебя в коде, при
n2 = Round(n1+i*0.01, 2)
n3 = Round(n1+n1+i*0.01, 2)

n1-(n3-n2)*10000000000 => (1 - n1) * 10000000000
вобщем далеко не 0 получается
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37457911
Pavel09
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TPavel09, ерунда какая-то у тебя в коде,

Да, прошу прощения, переводил с другого языка, скобки забыл поставить, и еще кое-какие огрехи
Вот запусти:

Public n1
n1 = 10000.00
Public n2, n3, i
Public i1, i2
i1 = 0
i2 = 0
for i = 1 to 10000000
n2 = Round(n1+i*0.01, 2)
n3 = Round(n1+n1+i*0.01, 2)
if (n1-(n3-n2))*10000000000 = 0.00
i1 = i1 + 1
else
i2 = i2 + 1
endif
next
? i1, i2
...
Рейтинг: 0 / 0
Сравнение чисел double
    #37458089
XAndy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Pavel09,

все числовые значения в фоксе хранятся в виде сишных структур, где помимо типа и значения есть и ширина отображения (поиск по ev_width в хелпе). Фокс перед сравнением выполняет неявное округление. Посмотрите по ссылке Максимова пример

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
ln1 =  2 . 05 
ln2 =  100 
ln3 = ln1*ln2
ln4 =  205 
? STRCONV(BINTOC(ln3,"BR"), 15 )
? STRCONV(BINTOC(ln4,"BR"), 15 )
? ln3 = ln4
? ln3, ln4

получаем числа с разным внутренним представлением, числа по разному выводятся на экран, но сравнение их равно истине - см.рисунок
...
Рейтинг: 0 / 0
25 сообщений из 43, страница 1 из 2
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Сравнение чисел double
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]