Некоторые десятичные числа не могут быть точно представлены в виде двоичных чисел из-за внутреннего представления двоичных чисел с плавающей запятой. Например: округление 14,225 до двух десятичных цифр приводит не к 14,23, как можно было ожидать, а к 14,22.
Python :
In: round(14.225, 2)
Out: 14.22
Предположим, однако, что у нас есть строковое представление 14,225 как «14,225», мы должны быть в состоянии достичь желаемого округления «14,23» как строковое представление.
Этот подход можно обобщить с произвольной точностью.
Возможное решение Python 2/3
import sys
def round_string(string, precision):
assert(int(precision) >= 0)
float(string)
decimal_point = string.find('.')
if decimal_point == -1:
if precision == 0:
return string
return string + '.' + '0' * precision
all_decimals = string[decimal_point+1:]
nb_missing_decimals = precision - len(all_decimals)
if nb_missing_decimals >= 0:
if precision == 0:
return string[:decimal_point]
return string + '0' * nb_missing_decimals
if int(all_decimals[precision]) < 5:
if precision == 0:
return string[:decimal_point]
return string[:decimal_point+precision+1]
sign = '-' if string[0] == '-' else ''
integer_part = abs(int(string[:decimal_point]))
if precision == 0:
return sign + str(integer_part + 1)
decimals = str(int(all_decimals[:precision]) + 1)
nb_missing_decimals = precision - len(decimals)
if nb_missing_decimals >= 0:
return sign + str(integer_part) + '.' + '0' * nb_missing_decimals + decimals
return sign + str(integer_part + 1) + '.' + '0' * precision
Использование :
# No IEEE 754 format rounding
In: round_string('14.225',2)
Out: '14.23'
# Trailing zeros
In: round_string('123.4',5)
Out: '123.40000'
In: round_string('99.9',0)
Out: '100'
# Negative values
In: round_string('-99.9',0)
Out: '-100'
In: round_string('1',0)
Out: '1'
# No unnecessary decimal point
In: round_string('1.',0)
Out: '1'
# No unnecessary decimal point
In: round_string('1.0',0)
Out: '1'
In: for i in range(8):
print(round_string('123456789.987654321',i))
Out: 123456790
123456790.0
123456789.99
123456789.988
123456789.9877
123456789.98765
123456789.987654
123456789.9876543
задача
Входной аргумент 1 : строка, содержащая
- по меньшей мере , одна цифра (
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
), - не более одной десятичной точки (
.
), которой должна предшествовать хотя бы одна цифра, - необязательный минус (
-
) в качестве первого символа.
Входной аргумент 2 : неотрицательное целое число
Вывод : правильно округленная (базовая 10) строка
округление = округлить до половины от нуля
Это код-гольф . Наименьшее количество байтов побеждает!
round(A,B
5 байтов0
это не положительное целое число, это «неотрицательное».123.4 & 5 --> 123.40000
? Или мы можем предположить, что второй вход никогда не будет больше количества десятичных знаков после точки в первом входе?Ответы:
APL (Дьялог) , 4 байта
Dyalog APL использует достаточную внутреннюю точность.
Попробуйте онлайн!
⍎⍞
выполнить ввод строки⎕⍕
получить числовой ввод и использовать его в качестве точности для форматированияисточник
Perl,
2220 байтС помощью:
Это дада версия кода. Предыдущая:
источник
printf"%.*f",pop,pop
должен работатьPHP,
3331 байтPHP тоже корректно округляется (хотя бы на 64 бит):
принимает входные данные из аргументов командной строки. Беги с
-r
.PHP, без встроенных модулей, 133 байта
Запустите
-nr
или протестируйте его онлайн .сломать
Нулевой байт не работает; поэтому я должен использовать
substr
.источник
"%.$argv[2]f"
вместо"%.{$argv[2]}f"
, сохраняя 2 байта.Рубин 2.3, 12 + 45 = 57
Использует
BigDecimal
встроенный, но это необходимо сделать перед использованием, что дешевле сделать как флаг.флаг:
-rbigdecimal
функция:
Ruby 2.3 по умолчанию использует
ROUND_HALF_UP
источник
Javascript (ES6), 44 байта
Попробуйте онлайн:
источник
Python,
114105103969189 байтСохранено 5 байтов благодаря Кевину Круйссену
Сохранено 2 байта благодаря Крэзору
Попробуйте онлайн!
источник
from decimal import *
и удаление трехd.
на 4 байта короче.d=Decimal
иd()
, что бы сохранить еще 5 (может быть неправильно, очень сонный)REXX, 24 байта
Поскольку REXX всегда использует текстовое представление чисел, правильное округление чисел бесплатно.
Попробуйте онлайн!
источник
BASH,
262321 байтПрименение
сохранить в round_string.sh, chmod + x round_string.sh
редактировать: нет необходимости загружать библиотеку
источник
14.22
для ввода14.225 2
, а не14.23
AHK, 25 байт
И снова меня срывает неспособность AHK использовать переданные в параметрах параметры напрямую в функциях, которые принимают либо имя переменной, либо число. Если я заменю
a
с1
вRound
функции, она использует значение1
. Если я пытаюсь%1%
, он пытается использовать содержимое первого аргумента в качестве имени переменной, что не работает. Необходимость установить его как другую переменную сначала стоила мне 6 байтов.источник
Пакетный, 390 байтов
Объяснение. Начинается с извлечения знака, если это применимо. Затем разбивает число на целые и дробные цифры. Фракция дополняется
n+1
нулями, чтобы убедиться, что она содержит не толькоn
цифры.n
Й (нулевой индексированный) цифра делится на 5, и это начальный перенос. Целые иn
дробные цифры объединяются, и перенос переносится символ за символом. (Дополнительные нули защищают от пульсации переноса.) После прекращения пульсации переноса число восстанавливается и вставляется любая десятичная точка.источник
TI-Basic,
5316 байтTI-Basic не использует IEEE, и метод ниже работает для 0-9 (включительно) десятичных позиций.
Спасибо @JulianLachniet за показ, что у CE calcs есть
toString(
команда, о которой я не знал (требуются Color Edition calcs OS 5.2 или выше).PS У меня была вторая строка,
sub(Str1,1,N+inString(Str1,".
но потом я понял, что это бесполезно.источник
N
используется?Java 7,
777271 байт-1 байт благодаря @cliffroot
72-байтовый ответ:
В отличие от Python, Java уже округляется правильно и уже возвращает String при использовании
String.format("%.2f", aDouble)
с2
заменой на количество десятичных разрядов, которое вы хотите.РЕДАКТИРОВАТЬ / ПРИМЕЧАНИЕ: Да, я знаю,
new Float(n)
что на 1 байт корочеnew Double(n)
, но, очевидно, это не сработает для тестовых случаев с123456789.987654321
. Смотрите этот тестовый код относительно Double против Float.Объяснение:
Тестовый код:
Попробуй это здесь.
Вывод:
источник
<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
123456789.987654321, 4
должно быть123456789.9877
, а не123456789.9876
Python (2/3), 394 байта
Работает для произвольных чисел точности.
источник
s[0]<'0'
и может также использовать строку умножение,m='-'*(s[0]<'0')
. Строки без интервалов оператора блока могут быть объединены вместе;
(напримерo='';c=0
). Некоторыеif
операторы, вероятно, можно заменить индексированием списков, чтобы еще больше сократить разрывы строк и табуляции. В последней строке может использоваться фрагментo[::-1]
,reversed(o)
а не''.join
является избыточным. Вы также можете переписать его, чтобы избежать необходимости использовать несколькоreturn
операторов.JavaScript (ES6), 155 байт
Объяснение: Строка сначала нормализована, чтобы содержать
.
иn+1
десятичные цифры. Затем учитываются последние цифры, любые предшествующие9
s или.
s и любая предыдущая цифра. Если последняя цифра меньше 5, то она и любые предшествующие ей цифры.
просто удаляются, но если она больше 5, то9
s изменяются на0
s, а предыдущая цифра увеличивается (или с префиксом 1, если предыдущей цифры не было).источник
Python 3 + SymPy, 54 байта
Попробуйте онлайн!
источник
Скала, 44 байта
Тестовое задание:
источник
Чудо , 10 байт
Применение:
Установите десятичную точность и добавьте конечные нули, если необходимо.
источник
npm i -g wonderlang
. Используйтеwonder
команду, чтобы запустить REPL, и вставьте код.J,
2217 байтСпасибо @Conor O'Brien за исправление моего понимания правил.
источник
2 t '1234.456'
следует дать1234.46
вместо6 t '1234.456'