atof случайно не работает корректно

Кажется, у меня возникла какая-то странная проблема с функцией atof(), которая неправильно конвертирует некоторые значения. Для тех же значений atoi() работает отлично.
Вот небольшой фрагмент того, что я делаю:

...
// frequencies is a std::string in format a10d50f20 etc. i.e. letter|frequency in %  
// 6 - 48 characters, always correctly formatted 
for (size_t i = 0; i < frequencies.size(); i+=3)
{
  // #1
  double percentage = atof(frequencies.substr(i+1, i+2).c_str()) / 100;
  // #2
  double percentage = static_cast<double>(atoi(frequencies.substr(i+1, i+2).c_str())) / 100;

  cout << frequencies[i] << " - " << percentage << endl;
}
...

По какой-то странной причине только метод № 2 всегда работает правильно.

Примеры результатов

ДЛЯ: частоты = "a30b30c40"

Оба метода работают правильно, что дает мне:
a – 0,30
b – 0,30
c – 0,40

ДЛЯ: частоты = "a10b10c10d10e10f50"

с atof() я получаю:
a - 0,10
b - 0,10
c - 1000000000,00 !?
d - 1000000000,00 !?
e - 0,10
f - 0,50
в то время как atoi() правильно дает мне следующее:
a - 0,10
b - 0,10< ш> в - 0,10
г - 0,10
д - 0,10
е - 0,50

p.s. Я не могу использовать std::stod, потому что mingw...


person jakubtabisz    schedule 17.04.2014    source источник


Ответы (2)


Второй аргумент substr — это длина, а не смещение.

Когда вы вызываете substr(i+1, i+2) вместо d, вы получаете всю оставшуюся часть строки, которая затем анализируется как экспоненциальная запись 10e10, т. е. 10 * 1010.

person ecatmur    schedule 17.04.2014
comment
+1. В стороне: в мире fortran d в 10d10 означает число с двойной точностью в представлении с плавающей запятой. Некоторые версии atof знают об этом, и, видимо, поэтому 10d10 также интерпретировалось как 10*10^10. - person David Hammen; 17.04.2014

Для d функция atof приняла 10e10 как 10 x (10 ^ 10) = 1000000000,0 (в инженерной записи/стандартной форме).

Вы действительно получили 1000000000.0 за c? Я не знаю, было ли то же самое.

person Community    schedule 17.04.2014