programming languages - ¿Qué lenguajes de programación admiten la aritmética de precisión arbitraria?
programming-languages bigdecimal (15)
Algunos idiomas tienen incorporado este soporte. Por ejemplo, eche un vistazo a java.math.BigDecimal en Java o decimal.Decimal en Python.
Otros idiomas frecuentemente tienen una biblioteca disponible para proporcionar esta característica. Por ejemplo, en C puede usar GMP u otras opciones.
La sección "Software de precisión arbitraria" de este artículo ofrece un buen resumen de sus opciones.
¿Qué lenguajes de programación admiten la aritmética de precisión arbitraria y podría dar un pequeño ejemplo de cómo imprimir una cantidad arbitraria de dígitos?
En Common Lisp,
(format t "~D~%" (expt 7 77))
"~ D ~%" en formato printf sería "% d / n". La aritmética de precisión arbitraria está integrada en Common Lisp.
Java de forma nativa puede hacer operaciones bignum con BigDecimal. GMP es la biblioteca estándar de facto para bignum con C / C ++.
Mucha gente recomendó el módulo decimal de Python, pero recomendaría usar mpmath sobre decimal para cualquier uso numérico serio.
Scheme (una variación de lisp) tiene una capacidad llamada ''bignum''. hay muchas implementaciones de buen esquema disponibles tanto en entornos de lenguaje completo como en opciones de scripts incrustables. algunos a los que puedo responder
MitScheme (también denominado esquema gnu) PLTScheme Chezscheme Guile (también proyecto gnu) Esquema 48
Si quieres trabajar en el mundo de .NET puedes usar la clase java.math.BigDecimal. Simplemente agregue una referencia a vjslib (en el marco) y luego puede usar las clases de Java.
Lo mejor es que se pueden usar desde cualquier lenguaje .NET. Por ejemplo en C #:
using java.math;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
BigDecimal bd = new BigDecimal("12345678901234567890.1234567890123456789");
Console.WriteLine(bd.ToString());
}
}
}
COBOL
77 VALUE PIC S9(4)V9(4).
una variable con signo de 4 decimales.
PL / 1
DCL VALUE DEC FIXED (4,4);
:-) No recuerdo las otras cosas viejas ...
Bromas aparte, como lo muestra mi ejemplo, creo que no debe elegir un lenguaje de programación que dependa de una característica única. Prácticamente todo el lenguaje decente y reciente admite la precisión fija en algunas clases dedicadas.
Mathematica.
N[Pi, 100]
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
La matemática no solo tiene precisión arbitraria, sino que, por defecto, tiene una precisión infinita. Mantiene cosas como 1/3 como racionales e incluso expresiones que involucran cosas como Sqrt [2] que mantiene simbólicamente hasta que pides una aproximación numérica, que puedes tener para cualquier número de decimales.
Aparentemente Tcl también los tiene, de la versión 8.5, cortesía de LibTomMath:
http://wiki.tcl.tk/5193 http://www.tcl.tk/cgi-bin/tct/tip/237.html http://math.libtomcrypt.com/
Smalltalk admite precisión arbitraria enteros y fracciones desde el principio. Tenga en cuenta que la implementación de gnu Smalltalk utiliza GMP bajo el capó. También estoy desarrollando ArbitraryPrecisionFloat para varios dialectos (Squeak / Pharo Visualworks y Dolphin), consulte http://www.squeaksource.com/ArbitraryPrecisionFl.html
Los números enteros de Ruby y los números de coma flotante (matemáticamente hablando: números racionales) no están estrictamente atados estrictamente a los límites clásicos relacionados con la CPU. En Ruby, los enteros y flotantes se cambian automáticamente, de forma transparente, a algunos "tipos de bignum", si el tamaño excede el máximo de los tamaños clásicos.
Es probable que uno desee usar una biblioteca matemática razonablemente optimizada y "completa" que use los "bignums". Aquí es donde el software de Mathematica realmente brilla con sus capacidades.
A partir de 2011, el Mathematica es extremadamente costoso y está terriblemente restringido desde el punto de vista de pirateo y reenvío, especialmente si uno desea enviar el software matemático como componente de una aplicación web pequeña, de bajo precio o un proyecto de código abierto. Si uno necesita hacer solo crujidos de números crudos, donde las visualizaciones no son necesarias, entonces existe una alternativa muy viable a Mathematica y Maple. La alternativa es el Sistema de Álgebra Computacional REDUCE, que es basado en Lisp, de código abierto y maduro (durante décadas) y en desarrollo activo (en 2011). Al igual que Mathematica, REDUCE usa el cálculo simbólico.
Para el reconocimiento de Mathematica, digo que a partir de 2011 me parece que Mathematica es el mejor en visualizaciones interactivas, pero creo que desde el punto de vista de la programación hay alternativas más convenientes incluso si Mathematica fuera un proyecto de código abierto. Para mí, parece que el Mahtematica también es un poco lento y no es adecuado para trabajar con grandes conjuntos de datos. Me parece que el nicho de Mathematica es la matemática teórica, no el crujir de números en la vida real. Por otro lado, el editor de Mathematica, Wolfram Research, está hospedando y manteniendo uno de los sitios de referencia matemáticos de más alta calidad, si no de la más alta calidad, de libre uso en el planeta Tierra: http: // mathworld. wolfram.com/ El sistema de documentación en línea que viene incluido con Mathematica también es realmente bueno.
Cuando hablamos de velocidad, vale la pena mencionar que se dice que REDUCE se ejecuta incluso en un enrutador Linux. El REDUCE está escrito en Lisp, pero viene con 2 de sus propias implementaciones específicas de Lisp. Uno de los Lisp se implementa en Java y el otro se implementa en C. Ambos funcionan decentemente, al menos desde el punto de vista matemático. El REDUCE tiene 2 modos: el tradicional "modo matemático" y un "modo de programador" que permite el acceso completo a todos los internos por el idioma en el que REDUCE está escrito: Lisp.
Entonces, mi opinión es que si uno mira la cantidad de trabajo que se necesita para escribir rutinas matemáticas, sin mencionar todos los cálculos simbólicos que son todos MADUROS en el REDUCE, entonces uno puede ahorrar una enorme cantidad de tiempo (décadas, literalmente ) haciendo la mayor parte de la parte matemática en REDUCE, especialmente dado que ha sido probado y depurado por matemáticos profesionales durante un largo período de tiempo, utilizado para hacer cálculos simbólicos en supercomputadoras de la era antigua para tareas profesionales reales y funciona maravillosamente, realmente rápido , en computadoras modernas de gama baja. Tampoco se me ha caído, a diferencia de al menos un paquete comercial que no quiero mencionar aquí.
http://www.reduce-algebra.com/
Para ilustrar, donde el cálculo simbólico es esencial en la práctica, traigo un ejemplo de cómo resolver un sistema de ecuaciones lineales mediante la inversión de la matriz. Para invertir una matriz, uno necesita encontrar determinantes. El redondeo que tiene lugar con los tipos de coma flotante soportados directamente por la CPU puede convertir una matriz que teóricamente tiene una inversa en una matriz que no tiene una inversa. Esto a su vez introduce una situación donde la mayoría del tiempo el software puede funcionar bien, pero si los datos son un poco "desafortunados", la aplicación falla, a pesar de que algorítmicamente no hay nada de malo en el software, aparte del redondeo de números de coma flotante.
Los números racionales de precisión absoluta tienen una seria limitación. Cuantos más cálculos se realizan con ellos, más memoria consumen. A partir de 2011 no conozco ninguna solución a ese problema, aparte de ser cuidadoso y hacer un seguimiento del número de operaciones que se han realizado con los números y luego redondear los números para ahorrar memoria, pero uno tiene que hacer el redondeo en una etapa muy precisa de los cálculos para evitar los problemas antes mencionados. Si es posible, entonces el redondeo debe hacerse al final de los cálculos como la última operación.
En PHP tienes BCMath. No necesita cargar ningún dll o compilar ningún módulo. Admite números de cualquier tamaño y precisión, representados como una cadena
<?php
$a = ''1.234'';
$b = ''5'';
echo bcadd($a, $b); // 6
echo bcadd($a, $b, 4); // 6.2340
?>
Hay varias bibliotecas de Javascript que manejan aritmética de precisión arbitraria.
Por ejemplo, usando mi biblioteca big.js :
Big.DP = 20; // Decimal Places
var pi = Big(355).div(113)
console.log( pi.toString() ); // ''3.14159292035398230088''
Python tiene tal habilidad. Hay un excelente ejemplo aquí .
Del artículo:
from math import log as _flog
from decimal import getcontext, Decimal
def log(x):
if x < 0:
return Decimal("NaN")
if x == 0:
return Decimal("-inf")
getcontext().prec += 3
eps = Decimal("10")**(-getcontext().prec+2)
# A good initial estimate is needed
r = Decimal(repr(_flog(float(x))))
while 1:
r2 = r - 1 + x/exp(r)
if abs(r2-r) < eps:
break
else:
r = r2
getcontext().prec -= 3
return +r
Además, el tutorial de inicio rápido de Python analiza la precisión arbitraria: http://docs.python.org/lib/decimal-tutorial.html
y describe getcontext:
la función getcontext () accede al contexto actual y permite cambiar la configuración.
Editar: Se agregó una aclaración sobre getcontext.
En R puede usar el paquete Rmpfr :
library(Rmpfr)
exp(mpfr(1, 120))
## 1 ''mpfr'' number of precision 120 bits
## [1] 2.7182818284590452353602874713526624979
Aquí puede encontrar la viñeta: Cálculo arbitrariamente preciso con R: el paquete Rmpfr