|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 ? Это не точное сравнение, а сравнение с учетом некоторой погрешности ? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 16:26 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Фокс хранит нумерик переменные как восьмибайтное двоичное с плавающей запятой. В хэлпе на фокс заявлена 16-тизначная точность и есть пометка что реально 15,95 знаков, т.е. не все 16-тизначные точно покажутся, у некоторых возможно изменение на 1 младшего разряда. Это связано с погрешностями преобразования десятичных чисел в восьмибайтное двоичное с плавающей запятой. И касается не только фокса, а всех прог использующих такой тип при расчетах. Твой пример у меня нормально отрабатывает Код: plaintext 1. 2. 3. 4. 5. 6.
Рекомендую почаще делать округление при расчетах Код: plaintext 1. 2. 3.
Код: plaintext 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 16:47 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
По поводу особенностей операций с 8-ми байтными double я в курсе, что результат операции может быть не 0, а какое-то очень малое значение. И по поводу типа Currency тоже. Вопрос заключается не в этом. В приведенном примере как раз возникает такой случай, и сравнение двух значений должно давать .F.. Но оно дает .T. Почему ? Как фокс сравнивает 2 числа double ? С учетом какой-то погрешности, так получается ? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 16:55 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima T Код: plaintext 1. 2. 3. 4. 5. 6.
Я уточню Исходя из того, что ? r*10000000000 && 0.0182 получается, что r не ноль, и сравнение с нулем должно давать .F. Если написать этот код на C, то так и получится Но фокс при сравнении с нулем дает .T. Значит, у фокса алгоритм сравнения не просто сравнение двух значений, а какой-то другой Меня интересует, какой ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 17:07 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Pavel09Dima T Код: plaintext 1. 2. 3. 4. 5. 6.
Я уточню Исходя из того, что ? r*10000000000 && 0.0182 получается, что r не ноль, и сравнение с нулем должно давать .F. Если написать этот код на C, то так и получится Но фокс при сравнении с нулем дает .T. Значит, у фокса алгоритм сравнения не просто сравнение двух значений, а какой-то другой Меня интересует, какой а как насчет поставить перед всем этим SET DECIMALS TO 18 и "конкретизировать четкость сравнения"? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 20:44 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 после выполнения сравнения, то новая настройка на последющие операции сравнения не повлияет. Свой вопрос я собственно задал для того, чтобы, возможно, в харборе использовать алгоритм сравнения фокса. Перенять, так сказать, передовой опыт. Но такой агоритм, я думаю, не подойдет. В любом случае, спасибо за ответы. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.09.2011, 21:17 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Вот здесь 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 ... |
|||
:
Нравится:
Не нравится:
|
|||
24.09.2011, 00:18 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
[quot Pavel09]SSn888.... Свой вопрос я собственно задал для того, чтобы, возможно, в харборе использовать алгоритм сравнения фокса. Перенять, так сказать, передовой опыт.... Явно это нигде не описано, но фокс кроме значения похоже хранит точность: количество десятичных знаков после запятой (возможно количество десятичных разрядов). И точность результата определяется точностью операндов и операцией. Например при сложении берется максимальная точность, при умножении - произведение точностей и т.д. Сравнение похоже идет с учетом точности сравниваемых значений. Код: plaintext 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2011, 07:46 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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." ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 01:12 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888, не совсем закончил ROUND тут не просто не "надо почаще", а "стоит пореже", чтоб не ввести себя самого нечаянно в заблуждение насчет надежности результата (если она определяется только автоприсвоенным типом данных и нашим ROUND) ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 01:14 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 08:18 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888SSn888, не совсем закончил ROUND тут не просто не "надо почаще", а "стоит пореже", чтоб не ввести себя самого нечаянно в заблуждение насчет надежности результата (если она определяется только автоприсвоенным типом данных и нашим ROUND) ROUND() надо там где он должен быть по логике задачи. Я это четко усвоил после войны с главбухом когда по одним и тем же расчетным данным итого не сошлось на копейку в разных отчетах, в обоих печаталось одинаково с точностью до копеек, а при расчете "итого" округлялось только в одном. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 08:36 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 13:49 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima TSSn888SSn888, не совсем закончил ROUND тут не просто не "надо почаще", а "стоит пореже", чтоб не ввести себя самого нечаянно в заблуждение насчет надежности результата (если она определяется только автоприсвоенным типом данных и нашим ROUND) ROUND() надо там где он должен быть по логике задачи. Я это четко усвоил после войны с главбухом когда по одним и тем же расчетным данным итого не сошлось на копейку в разных отчетах, в обоих печаталось одинаково с точностью до копеек, а при расчете "итого" округлялось только в одном. без обид но усваивать надо в результате обучения, чтения документации и так далее, а не как итог боевой операции. как я уже говорил - чтоб не ввести нечаянно самого себя в заблуждение. то, что Вы решили эту проблему роундом - вовсе не говорит, что это был единственный, и главное - наилучший вариант ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 13:52 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 точных десятичных знаков. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 14:48 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888И еще вот интересно - а для чего, следуя Вашей логике тогда разработчики вообще приделали это "AS " после декларирования переменной, если Вы утверждаете, что "оно ничего и не значит"? Я ж написал, для выдачи подсказок IntelliSense. Появилось это только в 7 или 8 фоксе. Можно написать Код: plaintext 1.
Код: plaintext
... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 15:10 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
мдя разговор вырождается в бодание... оно мне надо? ладно, ещ ответ 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) все равно система так построена что они по умолчанию при каждом вызове Камаз присылают" ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 15:20 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Что касается хэлпа то там очень мутно написали 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...." Тут перевод ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 15:22 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima T, человек, который даже после намеков действительно всеръез полагает, что я не могу перевести столь простую фразу - мне не интересен и пахнет снобизном, а не диалогом... желаю удачи, я самоустраняюсь от этого ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 15:28 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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.
Не типизированный язык VFP чего бы в хэлпе ни писали. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 15:36 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 разрядов не работает. Вот такая она, арифметика чисел с плавающей точкой. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 16:19 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888еще раз - по умолчанию, если нет явных объяв - фокс выделяет наиболее экономный вариант число 8.4546 никогда не встанет "само" double, потому что просто Num для него выгодней Экономный для чего? Чего экономим? Повторяю числовые типы для экономии места в DBF, поэтому с точки зрения переменных от такой экономии ни жарко ни холодно. Переменных в фоксе м.б. максимум 65535 поэтому не принципиально займут их значения 1 байт или 8. Переменным важнее экономия времени, т.е. производительность при расчетах. С этой точки зрения тип DOUBLE оптимален т.к. с ним процессор выполняет математические операции без каких либо предварительных преобразований. Заводить кучу типов переменных для хранения чисел тоже плохо, т.к. при расчетах необходимо будет делать приведение типов, на что надо время. К сожалению этот момент никак разработчиками не объясняется, как косвенный аргумент могу привести то что vartype() возвращает "N" для "Numeric, Float, Double, or Integer", т.е. все эти типы физически одинаково сохраняются в переменную при считывании из DBF, иначе зачем разработчикам объединять разные типы? CURENCY они ведь сюда не вставили, потому что он по другому физически хранится в переменной. Это восьмибайтное целое. SSn888Dima T, человек, который даже после намеков действительно всеръез полагает, что я не могу перевести столь простую фразу - мне не интересен и пахнет снобизном, а не диалогом... желаю удачи, я самоустраняюсь от этого Извини если чем обидел, не знаю как давно ты с фоксом работаешь (был опыт работы с VFP6 и ранее?), но предмет нашего спора это не изначально заложенный функционал, а сбоку прилепленный костыль с подачи маркетологов, прилепленный с целью прикрутить к фоксу подсказки при наборе кода в IDE, которые были в других языках на момент выхода VFP7 ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 16:30 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Pavel09, ерунда какая-то у тебя в коде, при n2 = Round(n1+i*0.01, 2) n3 = Round(n1+n1+i*0.01, 2) n1-(n3-n2)*10000000000 => (1 - n1) * 10000000000 вобщем далеко не 0 получается ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 16:43 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
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 ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 19:47 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Pavel09, все числовые значения в фоксе хранятся в виде сишных структур, где помимо типа и значения есть и ширина отображения (поиск по ev_width в хелпе). Фокс перед сравнением выполняет неявное округление. Посмотрите по ссылке Максимова пример Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
получаем числа с разным внутренним представлением, числа по разному выводятся на экран, но сравнение их равно истине - см.рисунок ... |
|||
:
Нравится:
Не нравится:
|
|||
27.09.2011, 23:10 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima TЗапустить религия не позволила? vartype(x) вернет тип LOGICAL т.к. всем переменным объявленным в LOCAL присваивается .F., потому что написанное после AS игнорируется при выполнении.для неинициализированных переменых объявленный тип и впрямь не имеет значения. Пока они не инициализированы. А теперь запишите туда раунд(5,233648б2) и покажите вартайп. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 07:35 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Pavel09, запустил, есть погрешность. Похоже на точность влияет не только кол-во знаков после запятой, но и изначальное общее количество знаков. Как выше писал ROUND() лечит проблему: Код: plaintext
Не знаю что твои числа означают, но если это деньги или что-то подобное по размерности, то подумай над использованием типа CURRENCY. Его придумали именно для тех случаев где даже малая погрешность недопустима в принципе. Конкретно в твоем примере замени и запусти: Код: plaintext
1. После каждой операции происходит округление до 4 знака, поэтому надо аккуратно делением пользоваться: Код: plaintext 1. 2.
Из плюсов: точность вычислений 18 знаков (больше будет ошибка переполнения), операции с CURRENCY выполняются немного быстрее чем с Numeric и Double. Лично я предпочитаю тип CURRENCY если его допустимо применить. Некоторые разработчики его не любят (в первую очередь из-за особенности деления). ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 08:02 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
tanglirDima TЗапустить религия не позволила? vartype(x) вернет тип LOGICAL т.к. всем переменным объявленным в LOCAL присваивается .F., потому что написанное после AS игнорируется при выполнении.для неинициализированных переменых объявленный тип и впрямь не имеет значения. Пока они не инициализированы. А теперь запишите туда раунд(5,233648б2) и покажите вартайп. Ничего не понял. Это к чему сказано? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 08:05 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima Ttanglirпропущено... А теперь запишите туда раунд(5,233648б2) и покажите вартайп. Ничего не понял. Это к чему сказано?К тому, что пока в переменной по умолчанию .F., то, конечно, вартайп вернёт L, это и ежу понятно. Но что вернёт вартайп, если в переменную заранее объявленного типа всё-таки записать значение, которое можно трактовать либо как объявленный тип, либо как какой-то другой. Вопрос-то в этом был, или я что-то пропустил? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 15:27 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
tanglirDima Tпропущено... Ничего не понял. Это к чему сказано?К тому, что пока в переменной по умолчанию .F., то, конечно, вартайп вернёт L, это и ежу понятно. Но что вернёт вартайп, если в переменную заранее объявленного типа всё-таки записать значение, которое можно трактовать либо как объявленный тип, либо как какой-то другой. Вопрос-то в этом был, или я что-то пропустил? Пропустил, если вкратце, то была попытка доказать что "local x as doub" создает переменную типа DOUBLE. В хэлпе так написано: MSDNLOCAL Command Visual Studio .NET 2003 Creates local variables and variable arrays. LOCAL Var1 [AS type [OF ClassLib]] ... VarList Specifies one or more local variables to create. [ARRAY] ArrayName1 (nRows1 [, nColumns1]) [, ArrayName2 (nRows2 [, nColumns2])] ... Specifies one or more local arrays to create. See DIMENSION for a description of each argument. AS type Specifies the data type on which this variable or array is based. .... Оно и правда написано, только далее MSDNRemarks ... Variables and arrays created with LOCAL are initialized to false (.F.)... Как хочешь так и понимай. Вобщем ерунды какой-то понаписали в хэлпе по поводу типизации переменных. Тут еще интересный опус: How to: Implement Strong Typing for Class, Object, and Variable Code ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 15:52 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Вобщем мое мнение: конструкция "AS ..." в фоксе нужна только чтобы подсказки выскакивали при наборе кода (свойства, методы объектов) и на работу кода она никак не влияет, т.е. при выполнении кода игнорируется. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2011, 15:59 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
> Автор: Dima T > Вобщем мое мнение: ... Полностью разделяю это мнение. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
29.09.2011, 14:22 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
автор> Автор: Dima T > Вобщем мое мнение: ... Полностью разделяю это мнение. Аналогично! ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 15:42 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Давно не заглядывал на форум.... вот наворочено-то :) Дима_Т, я не говорил ""local x as doub" создает переменную типа DOUBLE", тут у нас легкое недопонимание, из-за чего полагаю и возник сыр-бор. local x as doub описывает переменную, которая _после_ придания ей корректного значения будет держать это значение как DOUBLE. Разница в нюансах. А почему присваивает тип "поэкономней"... гм, потому что таков принцип фокса и не только его.. если по умолчанию присваивать наоборот, самые громоздкие типы - то рано или поздно начнуться проблемы.. например, с памятью. Пример с такси показался Вам недостаточно наглядным? ;) Или Вы наверно, везучий и по работе постоянно сталкиваетесь с новым железом и _не_ сталкивались с ситуацией "оперативка не более 256, причем половина ее уже забита всяким хламом" "Вобщем мое мнение: конструкция "AS ..." в фоксе нужна только чтобы подсказки выскакивали при наборе кода (свойства, методы объектов) и на работу кода она никак не влияет, т.е. при выполнении кода игнорируется."...ээээ мы на каких-то разных русских языках говорим, судя по всему :) какие нафиг подсказки если речь идет о _переменных_? Свойства и методы объектов касаются именно этих самых объектов, а какая подсказка по-Вашему должна вылезать при наборе переменной var1, объявленной как дубле? и в чем эта подсказка должна по-Вашему отличаться от переменной, объявленной AS INTEGER или AS еще много чего... Логика "для подсказок" сработает _только_ если объявляем AS Class... Во всех остальных случаях AS для подсказок не может быть использован, потому что ПОДСКАЗЫВАТЬ НЕЧЕГО. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 22:19 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888local x as doub описывает переменную, которая _после_ придания ей корректного значения будет держать это значение как DOUBLE. Разница в нюансах. Чушь полная . local x as double абсолютно идентично local x и создает логическую переменную, никакую не double. И значение после as double этой переменной можно присвоить ЛЮБОГО ТИПА, хоть двадцать раз as double напишите. Потому что в фоксе динамическая типизация, а as double служит вовсе не для указания типа, как Вы думаете. Вы, похоже, фокс в глаза не видели :) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 23:18 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
XAndy, У Вас в Киеве всегда так принято слету хамить свысока или (надеюсь) - это только Вы такой выдающийся? Мне что - скан трудовой сюда со стажем вфп выложить? Окстись, не спеши судить свысока! На вопрос "а зачем тогда возможность написать AS double", кстати - внятного ответа так и не получил ("для подсказки" не канает - см. выше) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.10.2011, 23:54 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888Давно не заглядывал на форум.... вот наворочено-то :) Дима_Т, я не говорил ""local x as doub" создает переменную типа DOUBLE", тут у нас легкое недопонимание, из-за чего полагаю и возник сыр-бор. local x as doub описывает переменную, которая _после_ придания ей корректного значения будет держать это значение как DOUBLE. Разница в нюансах. XAndy выше упоминал структуру ev_width , это и есть внутреннее хранение переменной в памяти: MSDN Value Structure Definition// An expression's value. Typedef struct { char ev_type; char ev_padding; short ev_width; unsigned ev_length; long ev_long; double ev_real; CCY ev_currency; MHANDLE ev_handle; ULONG ev_object; } Value; Value Structure Fields The following table is a guide to the values you can pass and receive in the Value structure for different types of data. Only the structure fields listed for a data type are used for that data type. Contents of Value structure for different data types Data typeStructure fieldValueNumericev_type'N'ev_widthDisplay widthev_lengthDecimal placesev_realDouble precision Нет там нескольких типов для нецелых чисел, только DOUBLE SSn888А почему присваивает тип "поэкономней"... гм, потому что таков принцип фокса и не только его.. если по умолчанию присваивать наоборот, самые громоздкие типы - то рано или поздно начнуться проблемы.. например, с памятью. Я уже писал что не память надо экономить. Считаем: 65535 - максимально возможное количество переменных в фоксе (по умолчанию 16384) 8 байт - под хранение DOUBLE т.е. под 65535 переменных DOUBLE надо 524280 байт, т.е. 0,5 Мб. Чего тут экономить? SSn888Или Вы наверно, везучий и по работе постоянно сталкиваетесь с новым железом и _не_ сталкивались с ситуацией "оперативка не более 256, причем половина ее уже забита всяким хламом" угу, есть еще вторые пни с W98 + 16Мб где действительно 6й фокс тормозит, правда стоит до 32Мб памяти добавить и все летает. SSn888какие нафиг подсказки если речь идет о _переменных_? Свойства и методы объектов касаются именно этих самых объектов, а какая подсказка по-Вашему должна вылезать при наборе переменной var1, объявленной как дубле? и в чем эта подсказка должна по-Вашему отличаться от переменной, объявленной AS INTEGER или AS еще много чего... Логика "для подсказок" сработает _только_ если объявляем AS Class... Во всех остальных случаях AS для подсказок не может быть использован, потому что ПОДСКАЗЫВАТЬ НЕЧЕГО. Немного истории фокса: в VFP6 (появился в 98м) подсказок не было и "AS" не было, после выхода SP5 мелкомягкие решили фокс похоронить, хоронили лет 5-6, потом неожиданно появилась 7-ка, следом в течении года 8-ка, в одной из которых это и появилось. Большая часть изменений были косметические, т.к. VFP6 имел устаревший вид прог под W95. Т.е. по-твоему в платформе которая была создана под слабые компы в очередной версии добавили оптимизацию переменных? Кстати это совсем немаленькая доработка. IntelliSence при подсказках пытается найти класс и вывести его свойства и методы, если не находит, то ничего не подсказывает. Повторяю, то что после AS игнорируется при выполнении, простой пример: Код: plaintext 1.
PS Не знаю как еще доказать отсутствие функционала, если ты считаешь что он все-таки есть - покажи пример кода при котором после добавления "AS ..." что-то изменится. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 07:58 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
Dima T, 1) AS не влияет на функционал (твое утверждение, с которым, как вижу, есть достаточное количество согласных) 2) AS касаемо основных типов не служит для подсказки (см. выше) И все-таки: А для чего тогда введено AS? В смысле - для чего оно введено для типов (с классами-то понятно)? Руководствуясь простой нормальной логикой - "если есть - значит для чего-то надо"... И, пожалуйста, не надо столь подробных экскурсов в историю. Тут - излишне. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 12:14 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
ХЗ почему так сделали, могу только свои предположения высказать: 1. Не факт что в хэлпе под data type подразумеваются простые типы, может под data type классы пользователя подразумеваются: MSDNAS type Specifies the data type on which this variable or array is based. OF ClassLib Specifies the class library containing the type description on which the type element of this variable or array is based. Для базовых классов фокса можно без OF писать: Код: plaintext
Код: plaintext
2. Примечание (подсказка) разработчику какого типа задумана переменная. Хотя для решения этой проблемы с типами многие используют венгерскую нотацию. Вобщем сделали это для классов и добавили игнорирование любых непонятных слов, как следствие получилось что после AS можно писать все что угодно. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 14:06 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888И все-таки: А для чего тогда введено AS? В смысле - для чего оно введено для типов (с классами-то понятно)? Руководствуясь простой нормальной логикой - "если есть - значит для чего-то надо"... Так Вам уже несколько раз объяснили. Это исключительно "дизайнерская" штука. В смысле, используется для раннего связывания на этапе написания программного кода. Не исполнения! Ну, например, если написать так Код: plaintext
То потом, в тексте кода, если написать имя переменной loExcel и поставить точку, то отобразится выпадающий список свойств и методов объекта Excel (разумеется, если он был зарегестрирован). Без необходимости предварительного создания экземпляра Excel. То же самое будет справедливо и для внутренних (пользовательских) классов FoxPro. Однако, повторюсь, это действует только и исключительно на этапе разработки приложения "Design Time". На этапе исполнения кода (даже не в EXE, а просто для отладки) опция "as" - ничего не значит. Игнорируется. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 14:10 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
SSn888это только Вы такой выдающийся? Всё относительно )))))))) Не понятно, почему Вам так трудно выполнить в среде разработки две строчки кода? Код: plaintext 1. 2.
... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 14:30 |
|
Сравнение чисел double
|
|||
---|---|---|---|
#18+
XAndy, я вообще-то не претендовал на роль святого :) Тем не менее - "да, я был не прав в таком-то моменте" вовсе не означает "Да, Дмитрий прав". Есть какой-то третий вариант. Уже просто из спортивного интереса пытаюсь его нащупать... "Нахрена оно на самом деле" Пока мало чего выходит, если найду - обязательно сюда тисну.. А насчет троллингов... Сударь, если Вам мерещаться гоблины или есть желание поругаться - обратитесь к зеркалу. Оно, падла, всегда покажет какой-нить прыщик :);) Мне же лично просто доставляет удовольствие общение (пусть и не всегда.. ээ.. ровное) с людьми тут :) ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2011, 16:45 |
|
|
start [/forum/topic.php?all=1&fid=41&tid=1584079]: |
0ms |
get settings: |
12ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
40ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
82ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 187ms |
0 / 0 |