2015-07-16 1 views
1

В VxSim, когда я запускаю strtod («1E1000000», 0) (в stdlib.h), он выполняется очень быстро (и возвращает 1), а strtod («1E1000000000000000000000000000», 0) занимает около 20 секунд, а затем возвращает 1. Иногда это всегда быстро и возвращает ненулевые значения, а затем нажатие ctrl-c и перезагрузка оболочки снова замедлят работу.Почему strtod замерзает при задании больших чисел в VxWorks?

Почему это происходит? В других операционных системах почти мгновенно.

я играл с этим более, а также в VxSim, когда вы бежите:

strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 
strtod("10", 0) 

Последняя дает:

значение = 1615516944 = 0x604ad510

Я испытал это на и этого не произошло, так что это может быть ошибка в VxSim.

Кроме того, компиляция этого также не дает вам этой ошибки. Только когда вы вводите их вручную в командной строке VxWorks и запускаете их там.

+1

По причинам ниже это действительно стоит сообщить. VxWorks используется во многих критически важных системах, и нетрудно представить, что эта проблема нашла свой путь в других базовых кодах. –

ответ

3

Оба числа намного превышают максимально допустимое конечное значение двойной точности IEEE 754, которое составляет около 1,79769e + 308. Существует мало оснований для преобразования «1E1000000000000000000000000000» в двойную точность, хотя в чувствительном к безопасности контексте это может быть хорошая атака «отказ в обслуживании», когда злоумышленнику разрешено вводить строку, предназначенную для преобразования в плавающую точку позже, и преобразование занимает больше времени, чем предполагал программист.

Поскольку для преобразования «1E1000000000000000000000000000» в двухмерную точность нет, одна из реализованных вами реализаций не реализовала оптимизацию, которая заключалась бы в распознавании этого случая и фактически выполняла множество вычислений (*) до понимая, что число намного больше, чем то, что может быть представлено в любом случае. В то время как другие, более умные реализации обнаруживают на ранних этапах, что показатель десятичной величины настолько велик, что конечный результат может быть только +inf и вернуться раньше.

Еще один интересный вход для поиска - «0.000 < 10000 zeroes> 1E10000». В этом случае неверно «оптимизированная» версия может ошибочно вернуть +inf.

Еще один интересный угловой случай - «0E1000000000000000000», который не должен возвращать ничего, кроме 0.0.

(*) преобразование десятичной в двоичную с плавающей запятой является более тонким, чем большинство людей понимают. См. this series of blog posts.

+1

Тот факт, что автор все еще находил угловые случаи для gcc, glibc и почтенного dtoa.c, всего 2 года назад, немного пугает. –

Смежные вопросы