Как отформатировать дубль, используя как можно больше значащих цифр? - PullRequest
0 голосов
/ 18 сентября 2011

Я хочу отформатировать двойное значение, указав столько цифр , сколько необходимо , чтобы сохранить то же значение.Я не хочу использовать экспоненциальную запись, потому что получатель строки нуждается в записи с плавающей запятой.

Примеры:

12.0 -> "12"
12.20300 -> "12.203"

РЕДАКТИРОВАТЬ: Спецификатор туда и обратно "R" , кажется, делает то, что мне нужно.По крайней мере, с числом, которое я тестировал, он работал как ожидалось.

Ответы [ 3 ]

0 голосов
/ 18 сентября 2011

Формат (x, "0. ################") очень близок, но после значащих цифр есть ненулевой мусор, который составляет cDbl(Format(x, "0.################")) <> x для большинство фракций.

Таким образом, вы можете получить намного больше цифр справа от десятичной запятой, но это не совсем практично (так как они являются мусорными цифрами) и, вероятно, не то, что вы ищете:

For i = 1 To ndigits
  s = s & Math.Floor(x * (10 ^ i)) Mod 10
Next i

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

0 голосов
/ 18 сентября 2011

Это на самом деле не может быть сделано. Во всяком случае, нетривиально и не использовать Doubles. Двойные числа просто не имеют достаточно цифр, чтобы вы могли отобразить любое число, поэтому, вероятно, научная нотация используется для отображения значений, когда вы просто вызываете .ToString ()

Результат, который мы получаем для двойников, находится в научной записи, потому что это лучше представляет значение. Используя этот код в качестве примера ....

    double testValue = 9123456789012345678.234;
    string formatStr = "{0:0.####################################################},{1}";
    Debug.WriteLine(String.Format(formatStr, testValue, testValue));

Вывод, который мы получаем:

9123456789012350000,9.12345678901235E + 18

Не фактическое число, с которого мы начали. Если вы игнорируете действительно большие цифры, я думаю, вы обнаружите, что опубликованные вами примеры не требуют от вас ничего делать.

 Debug.WriteLine(12.0d + " == " + String.Format("{0} == {1:0.########################}",  12.0d, 12.0d));
 Debug.WriteLine(12.20300d + " == " + String.Format("{0} == {1:0.########################}", 12.20300d, 12.20300d));
 Debug.WriteLine(-00.2900d + " == " + String.Format("{0} == {1:0.########################}", -00.2900d, -00.2900d));
 Debug.WriteLine(99999999999999999999999d + " == " + String.Format("{0} == {1:0.########################}", 99999999999999999999999d, 99999999999999999999999d));


12 == 12 == 12
12.203 == 12.203 == 12.203
-0.29 == -0.29 == -0.29
1E+23 == 1E+23 == 100000000000000000000000

В первых трех примерах, независимо от того, отображаете ли вы его непосредственно с помощью WriteLine, используете String.Format без форматной строки или "0. ########", вывод - это то, что вам нужно. Единственная ситуация, когда значение отличается, - это четвертый случай, когда поведение по умолчанию - научная запись. Изменение этого поведения даст вам цифры с дополнительными нулями, где вы ожидаете значимых чисел; но это может быть достигнуто, как Самир показал со строкой формата.

0 голосов
/ 18 сентября 2011

Вы можете использовать String.Format с пользовательской строкой форматирования, чтобы указать форматировщику печатать его именно так, как вам нужно. В этом случае вы хотите использовать модификатор в соответствии с 0.################. Этот форматер по существу указывает, что число должно иметь как минимум одну цифру перед десятичной запятой и до (но не обязательно) шестнадцати цифр после нее. К сожалению, у вас должен быть максимум, обозначаемый числом # символов, но 16 должно быть более чем достаточно.

String.Format("{0:0.################}", 12.20300);
...