C/C++ считая количество десятичных чисел?

Для файлов .nupkg, которые я люблю использовать:

Install-Package C:\Path\To\Some\File.nupkg
18
задан Milan 5 July 2009 в 01:30
поделиться

7 ответов

Я знаю два способа, ни один из них, к сожалению, не очень умный, но это скорее ограничение среды, а не меня: -)

Первый - sprintf число в большой буфер со строкой формата "%. 50f" , удалите конечные нули, а затем подсчитайте символы после десятичной точки. Это будет ограничено семейством printf . Или вы можете использовать строку как вводимую пользователем (вместо sprintf с плавающей запятой), чтобы полностью избежать проблем с плавающей запятой.

Второй - вычесть целую часть, а затем итеративно умножьте на 10 и снова вычтите целую часть, пока не получите ноль. Это ограничено пределами компьютерного представления чисел с плавающей запятой - на каждом этапе вы можете столкнуться с проблемой числа, которое не может быть представлено точно (поэтому .2155 может фактически быть .215499999998). Что-то вроде следующего (непроверено, за исключением моей головы, которая примерно соответствует COMX-35):

count = 0
num = abs(num)
num = num - int(num)
while num != 0:
    num = num * 10
    count = count + 1
    num = num - int(num)

Если вы знаете, какие числа вы получите (например, все они будут от 0 до 4 цифр) после десятичной точки), вы можете использовать стандартные "уловки" с плавающей запятой, чтобы сделать это правильно. Например, вместо:

while num != 0:

используйте

while abs(num) >= 0.0000001:
21
ответ дан 30 November 2019 в 07:18
поделиться

После того, как число преобразовано из пользовательского представления (строка, файл gif в формате OCR и т. Д.) В число с плавающей запятой, вы не обязательно имеете дело с одним и тем же числом. Таким образом, строгий, не очень полезный ответ - «Нет».

Если ( случай A ) вы можете избежать преобразования числа из строкового представления, проблема становится намного проще, вам нужно только посчитать цифры после десятичной точки и вычесть количество конечных нулей.

Если вы не можете этого сделать ( случай B ), тогда вам нужно сделать предположение о максимальном количестве десятичных знаков, преобразовать число обратно в строковое представление и округлите его до этого максимального числа, используя метод с округлением до четности . Например, если пользователь предоставляет 1.1, который представлен как 1.09999999999999 (гипотетически), преобразование его обратно в строку дает, угадайте что, "1.09999999999999". Округление этого числа, скажем, до четырех десятичных знаков дает «1,1000». Теперь вернемся к случаю A .

7
ответ дан 30 November 2019 в 07:18
поделиться

Что вы имеете в виду «свободно хранится (int»? Очевидно, что после сохранения в int у него остается ноль десятичных знаков. хранится в двоичной форме, поэтому нет очевидной или простой связи с десятичными знаками. Почему бы вам не сохранить ввод в виде строки,

2
ответ дан 30 November 2019 в 07:18
поделиться

Вне моей головы:

начнем с дробной части: .2155

многократно умножаем на 10 и отбрасываем целую часть числа, пока не получишь ноль. Число шагов будет числом десятичных знаков. например:

.2155 * 10 = 2.155
.155 * 10 = 1.55
.55 * 10 = 5.5
.5 * 10 = 5.0

4 шага = 4 десятичных цифры

4
ответ дан 30 November 2019 в 07:18
поделиться

Что-то вроде этого тоже может сработать:

float i = 5.2154;
std::string s;
std::string t;
std::stringstream out;
out << i;
s = out.str();

t = s.substr(s.find(".")+1);
cout<<"number of decimal places: " << t.length();
2
ответ дан 30 November 2019 в 07:18
поделиться

Я бы посоветовал читать значение как строку, искать десятичную точку и анализировать текст до и после него как целые числа. Нет ошибок с плавающей запятой или округления.

0
ответ дан 30 November 2019 в 07:18
поделиться

Один из способов - прочитать число в виде строки. Найдите длину подстроки после десятичной точки и сколько десятичных знаков ввел человек. Чтобы преобразовать эту строку в число с плавающей запятой, используя

atof (string.c_str ());

В другом примечании; При работе с операциями с плавающей запятой всегда рекомендуется хранить их в специальном объекте с конечной точностью. Например, вы можете хранить числа с плавающей запятой в особом типе объекта под названием «Десятичный», где целая и десятичная части числа являются целыми числами. Таким образом, у вас есть конечная точность. Обратной стороной этого является то, что вам нужно выписывать методы для арифметических операций (+, -, *, / и т.д.), но вы можете легко перезаписывать операторы в C ++. Я знаю, что это отклоняется от вашего первоначального вопроса, но это Всегда лучше хранить десятичные дроби в конечном виде. Таким образом вы также можете ответить на свой вопрос о том, сколько десятичных знаков в числе.

-1
ответ дан 30 November 2019 в 07:18
поделиться