Algunos números decimales no se pueden representar con precisión como flotantes binarios debido a la representación interna de los flotantes binarios. Por ejemplo: redondear 14.225 a dos dígitos decimales no da como resultado 14.23 como cabría esperar sino 14.22.
Python :
In: round(14.225, 2)
Out: 14.22
Sin embargo, supongamos que tenemos una representación de cadena de 14.225 como '14 .225 ', deberíamos poder lograr nuestro redondeo deseado '14 .23' como una representación de cadena.
Este enfoque puede generalizarse con precisión arbitraria.
Posible solución de 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
Uso :
# 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
Tarea
Argumento de entrada 1 : una cadena que contiene
- al menos un dígito (
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
), - como máximo un punto decimal (
.
) que debe estar precedido por al menos un dígito, - un menos opcional (
-
) como primer carácter.
Argumento de entrada 2 : un entero no negativo
Salida : la cadena correctamente redondeada (base 10)
redondeo = redondear la mitad lejos de cero
Este es un código de golf . ¡El número más bajo de bytes gana!
round(A,B
5 bytes0
no es un entero positivo, es "no negativo".123.4 & 5 --> 123.40000
? ¿O podemos suponer que la segunda entrada nunca será mayor que la cantidad de decimales después del punto en la primera entrada?Respuestas:
APL (Dyalog) , 4 bytes
Dyalog APL utiliza suficiente precisión interna.
Pruébalo en línea!
⍎⍞
ejecutar entrada de cadena⎕⍕
obtenga una entrada numérica y úsela como precisión para formatearfuente
Perl,
2220 bytesUtilizando:
Es la versión de código de Dada. Anterior:
fuente
printf"%.*f",pop,pop
debería funcionarPHP
3331 bytesPHP también se redondea correctamente (al menos en 64 bits):
toma datos de los argumentos de la línea de comandos. Corre con
-r
.PHP, sin integraciones, 133 bytes
Ejecutar
-nr
o probarlo en línea .Descompostura
Un byte nulo no funciona; así que tengo que usar
substr
.fuente
"%.$argv[2]f"
lugar de"%.{$argv[2]}f"
guardar 2 bytes.Rubí 2.3, 12 + 45 = 57
Utiliza el
BigDecimal
incorporado, pero necesita ser requerido antes de su uso, lo cual es más barato que hacer como una bandera.la bandera:
-rbigdecimal
la función:
Ruby 2.3 utiliza por defecto
ROUND_HALF_UP
fuente
Javascript (ES6), 44 bytes
Pruébalo en línea:
fuente
Python,
114105103969189 bytesGuardado 5 bytes gracias a Kevin Cruijssen
Guardado 2 bytes gracias a Krazor
Pruébalo en línea!
fuente
from decimal import *
y eliminar los tresd.
es 4 bytes más corto.d=Decimal
yd()
, lo que ahorraría otros 5. (Podría estar equivocado, con mucho sueño)REXX, 24 bytes
Dado que REXX siempre usa la representación de números en el texto, el redondeo correcto de los números es gratuito.
Pruébalo en línea!
fuente
BASH,
262321 bytesuso
guardar en round_string.sh, chmod + x round_string.sh
editar: no es necesario cargar la biblioteca
fuente
14.22
para la entrada14.225 2
, y no14.23
AHK, 25 bytes
Una vez más, estoy frustrado por la incapacidad de AHK para usar parámetros pasados directamente en funciones que aceptan un nombre de variable o un número. Si reemplazo
a
con1
en laRound
función, usa el valor1
. Si lo intento%1%
, intenta usar el contenido del primer argumento como un nombre de variable, que no funciona. Tener que configurarlo como otra variable primero me costó 6 bytes.fuente
Lote, 390 bytes
Explicación. Comienza por extraer el signo, si corresponde. Luego, divide el número en dígitos enteros y fraccionarios. La fracción se rellena con
n+1
ceros para garantizar que tenga más den
dígitos. Eln
dígito th (indexado a cero) se divide por 5, y este es el carry inicial. Losn
dígitos enteros y fraccionarios se concatenan, y el acarreo se agrega carácter por carácter. (Los ceros adicionales protegen contra la ondulación de transporte). Después de que el transporte deja de ondularse, el número se reconstruye y se inserta cualquier punto decimal.fuente
TI-Basic,
5316 bytesTI-Basic no utiliza IEEE y el método siguiente funciona para posiciones decimales 0-9 (inclusive).
Gracias a @JulianLachniet por mostrar que los calcs CE tienen
toString(
comando que no conocía (se requieren calcs Color Edition OS 5.2 o superior).PD: tuve una segunda línea,
sub(Str1,1,N+inString(Str1,".
pero luego me di cuenta de que era inútil.fuente
N
usa?Java 7,
777271 bytes-1 byte gracias a @cliffroot
Respuesta de 72 bytes:
A diferencia de Python, Java ya se redondea correctamente y ya devuelve una cadena cuando la usa
String.format("%.2f", aDouble)
con2
reemplazado con la cantidad de decimales que desee.EDITAR / NOTA: Sí, sé que
new Float(n)
es 1 byte más corto quenew Double(n)
, pero aparentemente falla para los casos de prueba con123456789.987654321
. Vea este código de prueba con respecto a Double vs Float.Explicación:
Código de prueba:
Pruébalo aquí.
Salida:
fuente
<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
123456789.987654321, 4
debería ser123456789.9877
, no123456789.9876
Python (2/3), 394 bytes
Funciona para números de precisión arbitrarios.
fuente
s[0]<'0'
y también podría usar la multiplicación de cuerdas,m='-'*(s[0]<'0')
. Las líneas sin ningún intervalo de instrucción de bloque se pueden unir con;
(po='';c=0
. Ej .). Algunasif
declaraciones podrían ser reemplazadas por la indexación de listas para reducir aún más la necesidad de saltos de línea y pestañas. La línea final podría usar un segmentoo[::-1]
, en lugar dereversed(o)
y''.join
es redundante. Es posible que también pueda reescribirlo para evitar la necesidad de múltiplesreturn
declaraciones.JavaScript (ES6), 155 bytes
Explicación: La serie se normaliza primero en contener una
.
yn+1
dígitos decimales. Luego se considera el dígito final, cualquier9
s o.
s anterior y cualquier dígito anterior. Si el último dígito es menor que 5, entonces y cualquier precedente inmediato.
simplemente se eliminan, pero si es mayor que 5, los9
s se cambian a0
sy el dígito anterior se incrementa (o 1 con el prefijo si no había un dígito anterior).fuente
Python 3 + SymPy, 54 bytes
Pruébalo en línea!
fuente
Scala, 44 bytes
Prueba:
fuente
Maravilla , 10 bytes
Uso:
Establezca la precisión decimal y agregue ceros finales si es necesario.
fuente
npm i -g wonderlang
. Use elwonder
comando para activar el REPL y pegue el código.J,
2217 bytesGracias a @Conor O'Brien por corregir mi comprensión de las reglas.
fuente
2 t '1234.456'
debería dar en1234.46
lugar de6 t '1234.456'