Функция to_string добавляет нули

Я пытаюсь получить часть int и десятичную часть двойного числа. Вот как я это реализовал:

void func(double d)
{
    int intpart, decpart;
    intpart = d;
    string szDec = to_string(d);
    szDec = szDec.substr(szDec.find(".") + 1);
    decpart = stoi(szDec);
    m_iNom = intpart * decpart + 1;
    m_iDenom = decpart;
}

Перехожу на func 0.5, проблема возникает при попытке получить десятичную часть как целое число.

Вместо получения 5 to_String делает szDec = "0.500000000000000"

а при использовании функции substr() szDec = "0,500000"

оставив мне decpart = 500000 вместо 5.

Как остановить функцию to_String и функцию substr от добавления нулей к строке и преобразования ее в число с плавающей запятой?


person Tugal.44    schedule 27.09.2014    source источник
comment
Что не так с простым использованием std::modf   -  person Cubbi    schedule 27.09.2014
comment
@Cubbi Скажем, у меня 3,5, мне нужно 3, так как 5, а не 3 и 0,5   -  person Tugal.44    schedule 27.09.2014
comment
А если у вас 3.1? Когда вы сохраняете это в двойном, вы получаете 3.100000000000000088817841970012523233890533447265625. Вы хотите вернуть 3 и 100000000000000088817841970012523233890533447265625 или 3 и 1? И если вы хотите 3 и 1, как именно вы хотите, чтобы они вычислялись?   -  person Cubbi    schedule 27.09.2014
comment
почему, если я сохраняю 3.1, он добавляет все эти числа? И я бы хотел, чтобы исходное значение хранилось в int, поэтому 3 и 1   -  person Tugal.44    schedule 27.09.2014
comment
Другая проблема заключается в том, что 0.5 и 0.05 приведут к одному и тому же результату: десятичная часть будет 5.   -  person Jarod42    schedule 27.09.2014
comment
@ Jarod42, так что я могу сделать?   -  person Tugal.44    schedule 27.09.2014
comment
Если вы никогда не сохраните свое значение в double, вы не получите все эти числа. Если вы вводите десятичную дробь, оставьте ее десятичной дробью.   -  person Cubbi    schedule 27.09.2014
comment
@Cubbi Я должен сохранить его в двойном формате раньше, потому что до того, как эта функция будет вызвана, другая функция получит номер и передаст его этой функции.   -  person Tugal.44    schedule 27.09.2014
comment
@Tugal.44: Предложение Cubbi (std::modf) имеет смысл. Но похоже, что это проблема XY   -  person Jarod42    schedule 27.09.2014
comment
@ Jarod42 Jarod42 Я не понимаю, как modf может мне помочь, мне нужна часть dec как целое число   -  person Tugal.44    schedule 27.09.2014
comment
Используя ответ кубби: ideone.com/dXs4Rx   -  person Brandon    schedule 27.09.2014
comment
@ Брэндон, но * 10 произвольно, что, если это 3.10? или 3.100   -  person Tugal.44    schedule 27.09.2014
comment
Какая? 0,10 и 0,100 - это одно и то же, на самом деле. Если вам нужно сохранить точность, то я понятия не имею. Вам придется использовать строку и делать все это самостоятельно.   -  person Brandon    schedule 27.09.2014
comment
@Brandon здесь заключается проблема с преобразованием в строку с использованием to_string, он добавляет числа, которые искажают фактический ввод. 3.5 будет выглядеть как 3.5xxxxxxxxxx..   -  person Tugal.44    schedule 27.09.2014
comment
@Brandon Чтобы быть более ясным, я не имел в виду, что мне нужны 0, я знаю, например, что 0,1 = 0,10 и так далее, но если бы у меня было, например, 0,345, * 10 является произвольным и не будет работать, потому что 0,3! = 0,345   -  person Tugal.44    schedule 27.09.2014
comment
Да, но это трудно понять, потому что сохранение 0,5000 в двойном значении всегда будет храниться либо как 0,5, либо как 0,50000000000000000. Он не будет храниться как 0,5000. Вы должны сохранить это в строке или использовать строковый поток и применить к нему правильную точность.   -  person Brandon    schedule 28.09.2014


Ответы (1)


Чтобы ответить на ваш конкретный вопрос, std::to_string целенаправленно определяется быть максимально простым и не иметь никаких ручек, которые можно было бы повернуть, чтобы изменить выходной формат. Для чисел с плавающей запятой определено выполнение эквивалента %f языка C, который выдает ровно "0.50000" для ввода 0.5.

boost::lexical_cast<std::string>(d) даст вам "0.5", как и std::ostringstream buf; buf << d; szDec = buf.str();, или эквивалент C, но, как указано в комментариях, если ваше число не может быть представлено в двоичном виде (например, если оно 0,1, а не 0,5), то восстановление оптимальной десятичной дроби является нетривиальным алгоритмом.

person Cubbi    schedule 28.09.2014