![]() |
Модераторы: skyboy, MoLeX, Aliance, ksnk |
![]() ![]() ![]() |
|
Icaros |
|
||||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 26.5.2006 Репутация: нет Всего: нет |
Добрый день, уважаемые.
Столкнулся с серьезнейшей проблемой. Уже приличное время назад столкнулся с такой штукой: есть массив с данными, состоящий из 100 элементов, в цикле обращаюсь к элементам для их вывода. Вот код:
И вот это долгое время у меня имеется странный эффект:
Поначалу был, мягко скажем, в шоке... После экспериментов с пошаговым проходом по коду (спасибо Zend`у) обнаружил интересную особенность. При переводе числа из double в integer ПХП исходит из своих соображений, не совпадающих с моими. Т.е. число 0.11*100, переведенное в integer, станет 10. Вы спросите: а зачем так странно обращаться к массиву (т.е. 0,0х * 100)? Может и странно, но я был уверен, что нет никакой разницы и так было удобнее. Вот эта особенность морочила мне голову такое время... ![]() В одном из журналов PHPinside я читал (вот сейчас вдруг вспомнил, а тогда не придал значения), что в ПХП особый способ представления double (или integer) чисел. Там было сказано, что выражение 0 == 0.0 выдаст false (или как-то так) и надо пользоваться неким math (может ошибаюсь, но я не в курсе что это). Если быть короче, то как корректно перевести из double в integer ? Или, если это все ахинея, скажите, чтобы я учил учебник ПХП за первый класс церковно-приходской школы. |
||||
|
|||||
vasac |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1060 Регистрация: 4.5.2006 Репутация: 8 Всего: 36 |
Лично я не могу сказать с полным на то основанием, что это ахинея, по той причине, что слабо понял о чем здесь написано.
Опишите, пожалуйста, саму суть проблемы без кода этого ужасного цикла. Возможно Вы имеете ввиду особенности представления чисел с плавающей запятой, то да, double вообще сравнивать по большому счету нельзя, даже с double. Но это проблема (проблема ли) отнюдь не только php. Это сообщение отредактировал(а) vasac - 7.1.2007, 21:58 |
|||
|
||||
murod |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 17.9.2005 Где: Uzbekistan/Tashke nt Репутация: 2 Всего: 4 |
да есть такой глюк,
тебе надо так:
может и не глюк, но у меня нет обяснений. ![]() --------------------
Люди всего мира берегите природу! |
|||
|
||||
Icaros |
|
||||
Новичок Профиль Группа: Участник Сообщений: 30 Регистрация: 26.5.2006 Репутация: нет Всего: нет |
Вот что получалось у меня:
Код:
Результат:
Уважаемый murod, Вы совершенно правы. Спасибо. Чудеса. С Вашим хаком все встало на круги своя. Что же это за "особенность", попортившая мне нервы ?.. |
||||
|
|||||
Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 122 Всего: 261 |
Icaros, что за бред вы тут несете?
Я не понимаю, что религия не позволяет писать по человечески, как большинство нормальных людей?
|
|||
|
||||
murod |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 17.9.2005 Где: Uzbekistan/Tashke nt Репутация: 2 Всего: 4 |
Mal Hack, мне кажется Icaros просто забыл поставить знак $. ничего страшного. ты лучше скажи свое мнение что это такое? глюк или это мы- не из "большинства нормальных людей"?
![]() Добавлено @ 23:15 с типом String все работает правильно, а с Integer глюки --------------------
Люди всего мира берегите природу! |
|||
|
||||
Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 122 Всего: 261 |
murod, я уже привел свою точку зрения касательно кода в первом посте.
|
|||
|
||||
murod |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 17.9.2005 Где: Uzbekistan/Tashke nt Репутация: 2 Всего: 4 |
Mal Hack, кажется ты немножка не понял проблему
Icaros'а
выводит: 0 1 2 3 4 5 6 7 8 9 10 10 11 а этот код :
выводит: 0 1 2 3 4 5 6 7 8 9 10 11 12 именно с массивами работает не правильно!! вот без массива:
выводит правильно: 0 1 2 3 4 5 6 7 8 9 10 11 12 Добавлено @ 23:42 Народ как это понять? --------------------
Люди всего мира берегите природу! |
||||||
|
|||||||
vasac |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1060 Регистрация: 4.5.2006 Репутация: 8 Всего: 36 |
murod,
техническая проблема, как я уже указал, в представлении чисел с плавающей запятой. Насчет ее понимания — в поиск. глобальная же проблема в том, что вы творите здесь какую-то фигню и пытаетесь понять, почему же в итоге фигня и получается. |
|||
|
||||
Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 122 Всего: 261 |
||||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 75 Всего: 260 |
Mal Hack, но ведь такая проблема(а она, по-видимому, в наличии) вполне может выплыть в другом, внешне "вполне приличном" коде. Не в курсе, от чего такая ерунда при работе с хэшами?
|
|||
|
||||
Mal Hack |
|
|||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 122 Всего: 261 |
Какие хэши?
Судя по всему это баг в двоичном представлении числа... К сожалению, как хранятся числа во внутреннем представлении - вопрос, ответ на которой знают очень мало людей. |
|||
|
||||
ewolf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 389 Регистрация: 15.8.2006 Где: г. Москва Репутация: 8 Всего: 18 |
Причина такой ошибки, как мне кажется, состоит в следующем:
Из-за того, что числа в формате IEEE представляются в двоичной форме в формате [экспонента][мантисса]. В результате, некоторые десятичные дроби не могут быть точно представлены в этой записи. Об этом сказано тут например http://www.php.net/manual/ru/language.types.float.php В результате при постепенном добавлении к переменной значения 0.01 к 11 шагу накапливается ошибка, и вместо числа 11 мы храним число 10.9999999999999999. Ключ может быть только либо строкой, либо целым числом, поэтому у числа 10.(9) отбрасывается дробная часть. И мы получаем значение 10. При преобразовании в строку алгоритм окруления другой и преобразует дробное число в целое, основываясь на количестве разрядов после запятой. Сравните, например
В этом и причина "ошибки" Это сообщение отредактировал(а) ewolf - 8.1.2007, 01:19 |
|||
|
||||
Mal Hack |
|
||||||||
![]() Мудрый... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 9926 Регистрация: 15.2.2004 Репутация: 122 Всего: 261 |
Хм... Знал я конечно, о такой фишке, но не думал, что в PHP на столько это криво реализовано..
на выходе получаем:
Хм.... Вот написал тестик на С++...
Результаты:
|
||||||||
|
|||||||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 75 Всего: 260 |
да уж. почему бы не округлять-то? спасибо за приведенные тесты, Mal Hack, ewolf.
Кстати, Mal Hack, всё же не только в кривости кода дело, верно? ![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "PHP" | |
|
Новичкам:
Важно:
Внимание:
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | PHP: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |