...

четверг, 21 августа 2014 г.

Баг Double.parseDouble() в Android

В поисках эпизодически вылезающей ошибки, наткнулся на неожиданное поведение метода Double.parseDouble() . Исполнение кода

Double.parseDouble("4cff9d79-a696-4dfc-89f9-a265ae117257")




не привело к выбрасыванию исключения NumberFormatException. Код вполне корректно отработал и выдал результат — Infinity .



Мягко говоря, я удивился. Проверил. С десятками других UUID'ов метод отрабатывал корректно, но вот конкретно с этим (и некоторыми, иногда попадающимися, другими) Android вел себя немного загадочно.

Проверка в десктопной Java подтвердила мою догадку — проблема только в Android'е.


В чем же дело? Покопавшись, я обнаружил, что проблема вот в этом коде, который исполняется при вызове parseDouble() :



if (result.e < -1024) {
result.zero = true;
return result;
} else if (result.e > 1024) {
result.infinity = true;
return result;
}


Double, как известно, имеет и экспоненциальную запись MeP, где M — мантисса, а P — экспонента (т.е., данная запись аналогична M*10^P). Android же в (почти) первую очередь проверяет на наличие экспоненты, и увидев, что она есть, и она больше, чем 1024, признает всё число бесконечностью и на этом все проверки прекращает. По этому же коду можно увидеть, что в случае, если после буквы e идет любое отрицательное число, меньшее 1024, то число также признается корректным, но равным уже нулю.


Действительно:



Double.parseDouble("Случайный набор символовe1025"); //Infinity
Double.parseDouble("Случайный набор символовe-1025"); //0.0




Ну и более реалистичный вариант (с UUID'ами):

Double.parseDouble("4cff9d79-a696-4dfc-89f9-a265ae117257"); //Infinity
Double.parseDouble("4cff9d79-a696-4dfc-89fe-126534117257"); //0.0




В общем, использовать данный метод при программировании под Android не безопасно. Используйте другие альтернативы.

P.S. Никогда не сталкивался с багами Android. Наверняка у них есть какой-то баг-трекер, где можно найти зафиксирован ли уже кем-то этот баг и, в случае необходимости, добавить его. И наверняка среди аудитории хабра есть знающие люди, которые могут подсказать как это сделать (ну либо сделают это сами). Заранее спасибо.


P.P.S. Исходники я смотрел для API 17, баг возникал на телефоне с Android 4.4.2.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий