Почему степени 10 печатаются в научной нотации в 5-й степени?


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

Во-первых, мои scipen и digits настройки

unlist(options("scipen", "digits"))
# scipen digits 
#      0      7 
Теперь степени 10 обычно печатаются до 4-й степени, а затем печать переключается на научную нотацию в 5-й степени.
10^(1:4)
# [1]    10   100  1000 10000
10^(1:5)
# [1] 1e+01 1e+02 1e+03 1e+04 1e+05

Интересно, что этого не происходит для некоторых других числа больше 10.

11^(1:5)
# [1]     11    121   1331  14641 161051

Судя по следующему, 5 цифр кажутся значимыми.

100^(1:2)
# [1]   100 10000
100^(1:3)
# [1] 1e+02 1e+04 1e+06

Итак, мои вопросы таковы:

Почему научная нотация активируется между 4-й и 5-й степенями для 10, а не для других чисел? Имеет ли значение число 5? Кроме того, почему 5, а не число ближе к максимальному варианту цифр 22?
2 41

2 ответа:

Ну, ответ на самом деле есть в определении scipen в ?options, хотя довольно трудно понять, что это означает, не играя с некоторыми примерами:

'scipen': целое число. Штраф, который будет применяться при принятии решения о печати числовые значения в фиксированной или экспоненциальной нотации. Положительный смещение ценностей в сторону фиксированного и отрицательное в сторону научного нотация: фиксированная нотация будет предпочтительнее, если она не больше чем цифры ' scipen’ более широкий.

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

В третьем случае, однако, фиксированная нотация шире (т. е. "больше, чем 0 цифр шире"), потому что 5 нулей составляют больше символов, чем 4 символа, используемые для представления одного и того же значения с помощью e+nn. В результате в этом случае предпочтение отдается научной нотации .

1e+03
1000
# [1] 1000

1e+04
10000
# [1] 10000

1e+05
100000      ## <- wider
# [1] 1e+05
Затем рассмотрим некоторые числа, которые также заканчиваются множеством нулей, но для представления которых в научной системе счисления потребуется использовать a .. Для этих чисел научная нотация будет использоваться, если у вас есть 6 или более нулей (то есть больше, чем 5 символов, занятых одним . и символами e+nn).
1.1e+06
1100000
# [1] 1100000


1.1e+07
11000000     ##  <- wider
# [1] 1.1e+07

Рассуждение о компромиссе становится немного сложнее для большинства других чисел, например что значения обоих options("scipen") и options("digits") вступают в игру, но общая идея совершенно одинакова.

Чтобы увидеть некоторые из слегка неожиданных осложнений, которые вступают в игру, вы можете вставить следующее в консоль (возможно, после первой попытки предсказать, где в каждой серии произойдет переход к научной нотации).
100001
1000001
10000001
100000001
1000000001
10000000001
100000000001
1000000000001

111111
1111111
11111111
111111111
1111111111
11111111111
111111111111
1111111111111

Я в замешательстве относительно того, что именно является вашим вопросом; или, более конкретно, как бы вы использовали ответ на этот вопрос, чтобы каким-то образом изменить/контролировать поведение R. Вы пытаетесь форматировать числа определенным образом? Есть лучшие способы сделать это.

Когда вы вводите такие значения, результаты неявно выполняются, хотя одна из команд print() должна быть отформатирована "красиво" на консоли. Всякий раз, когда вещи должны выглядеть "красиво" на экране, код для этого часто уродлив. Здесь большая часть этот код заботятся formatReal функция, и помощник научные функции. Последний отслеживает следующую информацию для числа

/* for a number x , determine
 *  sgn    = 1_{x < 0}  {0/1}
 *  kpower = Exponent of 10;
 *  nsig   = min(R_print.digits, #{significant digits of alpha})
 *  roundingwidens = 1 if rounding causes x to increase in width, 0 otherwise
 *
 * where  |x| = alpha * 10^kpower   and  1 <= alpha < 10
 */
Затем первая функция использует эту информацию, чтобы попытаться сделать" красивые " числа, балансируя значения слева и справа от десятичного знака. Это комбинация многих вещей, таких как порядок величины числа и количество значащих цифр, а также влияние окружающей среды. вариант scipen и т. д.

print() только для того, чтобы все выглядело "красиво"."То, что именно приятно, зависит от всех значений в векторе. В этом коде вы найдете несколько жестких сокращений; он очень адаптивен. Нет простого способа кратко описать все, что он делает в общем случае (что звучит так, как будто вы просите).

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

Конечно, это поведение зависит от class(), и я указал на вещи formatReal, так как именно там происходят самые сложные вещи. Но обратите внимание на разницу, когда вы используете целые числа

c(10, 100, 1000, 10000, 100000)
# [1] 1e+01 1e+02 1e+03 1e+04 1e+05
c(10L, 100L, 1000L, 10000L, 100000L)
# [1]     10    100   1000  10000 100000