Длина дроби

Как получить длину дроби? Если возможно, без использования строковой операции или цикла

should all return length of 3:
5.234
5.23400
5.234000

Принимается любой язык программирования

[РЕДАКТИРОВАТЬ]

Не домашнее задание, я хочу отображать дроби по минимуму. Например, я определил числовое значение (18,8) в базе данных. Если пользователь ввел только 5.234, данные, сохраненные в базе данных, будут 5.23400000. Я просто хочу отобразить его только как 5.234


person Hao    schedule 25.02.2009    source источник


Ответы (6)


If Int(num) = num Then Return 0
num *= 10
If Int(num) = num Then Return 1
num *= 10
If Int(num) = num Then Return 2
num *= 10
If Int(num) = num Then Return 3
num *= 10
If Int(num) = num Then Return 4
num *= 10
If Int(num) = num Then Return 5
num *= 10
If Int(num) = num Then Return 6
num *= 10
If Int(num) = num Then Return 7
num *= 10
If Int(num) = num Then Return 8
Throw New Exception("Number exceeds expected precision")

Никаких строковых операций, никаких циклов.

ИЗМЕНИТЬ:

Кстати, чтобы сделать это с помощью цикла:

result = 0
Do While (Int(num) !> num) 
    num *= 10
    result += 1
Loop
Return result

Чуть более элегантный

person Patrick McDonald    schedule 25.02.2009
comment
Этот хорош. Я собираюсь остановиться на повторном делении (я отказываюсь от идеи решения без цикла) и считаю до 0, но не могу этого сделать, так как дробь - это то, что мне нужно, а не целое число. Это хорошая логика! - person Hao; 26.02.2009

Учитывая, что вы беспокоитесь об отображении, а не о внутреннем представлении, почему бы просто не убрать конечные 0?

#!/use/bin/perl

my @nums = ( '5.234', '5.23400', '5.234000' );
$_ =~ s/0+$// for @nums;  # remove trailing 0s
$_ =~ s/\.$// for @nums;  # remove trailing .

print "@nums\n";

Вероятно, вы можете оптимизировать оба в одно регулярное выражение.

person codelogic    schedule 25.02.2009
comment
На самом деле 5.234 НЕ МОЖЕТ быть представлено в 64-битном целом IEEE 745, на самом деле оно будет приблизительно равно 5.233999999999999985789145284797996282577514648437500 ;-) - person Ustaman Sangat; 03.07.2012

Для не дробной части длина равна:

int((ln(v)/ln(10))+.999)

пока v > 1, где ln() — натуральный логарифм, а int() всегда округляется в меньшую сторону. Для v == 1 функция ln(v) возвращает 0, поэтому вы должны обрабатывать это в особом случае.

Должно быть возможно добиться того же для дробной части (v - int(v)), но моя математика меня подводит.

person Aaron Digulla    schedule 25.02.2009
comment
Я сомневаюсь, что что-либо, связанное с натуральным бревном, может иметь ценность. Поскольку String.format(%x, Double.doubleToRawLongBits(5.234)) дает 4014ef9db22d0e56, и это, сохраняя все цифры, оценивается как 5,2339999999999999857891452847979962825775146484375, тогда как 5,25 может быть представлено точно. 5,251 снова аппроксимируется как 5,25100000000000033395508580724708735942840576171875. Моя точка зрения заключается в том, что длина не является монотонной в случае дроби. - person Ustaman Sangat; 03.07.2012

Просто реализуйте алгоритм деления. И вы останавливаетесь, когда число > 7 или 8 цифр (для float32)

person wiwulo    schedule 25.02.2009

При использовании Java и JDBC получите значение через ResultSet.getBigDecimal(). Чтобы получить правильный масштаб, используйте этот код (Java 5 и выше; в Java 1.4 есть ошибка, которая приводит к сбою для «0.0»):

int precision = v.stripTrailingZeros().scale();

Для Java 1.4 см. эту страницу.

person Aaron Digulla    schedule 25.02.2009

В Java:

Double.valueOf("5.34000").toString();

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

person amit    schedule 26.02.2009