2011-11-08 4 views
6

Como proyecto personal, estoy trabajando en la implementación de un tipo de número de Precisión Arbitraria para un proyecto mío propio.¿Cómo determinar de antemano si un cálculo sin firmar puede desbordarse?

Ya conozco todas las bibliotecas populares, probadas y robustas que hacen esto. Quiero trabajar en una solución como un proyecto educativo de superación personal.

estoy investigando la zona y tratando de averiguar si hay alguna manera de más o menos predecir si una operación provocará un desbordamiento antes de que realmente hacen los cálculos. Tampoco estoy tan preocupado por los falsos positivos.

Quiero poder utilizar el espacio más pequeño que sea apropiado para el cálculo. Si el cálculo se mantiene dentro de sus límites nativos, lo mantengo allí.

Por ejemplo: Multiplying two 64 bit Integers if each are large enough will cause an overflow. quiero para detectar esto y hasta convertir los números a mi tipo de número sólo si el resultado puede superar los 64 bits de resolución. Trabajaré con con números firmados en este experimento.

¿Cuál es la forma más segura y eficiente de detectar un desbordamiento/desbordamiento?

+0

Nunca intenté un proyecto similar, por lo que solo recibí las siguientes preguntas: ¿de qué sirve conocer el desbordamiento de antemano? ¿Optimización para que los nichos más pequeños sean rápidos o algo menos obvio? ¿Necesitas una solución exacta o aceptar una que pueda dar falsas alarmas de desbordamiento? – vmatyi

+1

Su pregunta y su comentario en respuesta a una de las respuestas dicen que está utilizando operandos firmados, pero el título dice unsigned. ¿Cuál es?La aritmética sin signo es probablemente más fácil de manejar, y probablemente sea más adecuada para trabajar con números de precisión arbitrarios. –

+0

Haré cálculos arbitrarios firmados utilizando tipos de primitiva sin signo como componentes base, como en una matriz de largos de 64 bits sin signo que representan la base –

Respuesta

2

tomar sólo el bit más alto de los dos números, desviación a la izquierda por uno, si el resultado (por ejemplo: la multiplicación) de esos números podría causar un desbordamiento, usted tiene una buena oportunidad de un desbordamiento.

Aunque no es preciso, es sorprendentemente rápido y es un buen indicador de que necesita un tipo de datos más grande para el resultado.

Esto sólo podría tener sentido para las grandes tipos de datos para los que el operador es costoso, por las cosas simples (incluso para los números de 64 bits), creo que se puede confiar en la aritmética orden interna de la CPU .. ver esta pregunta: Undefined behavior when exceed 64 bits

+1

¿Por qué cambiar a la izquierda por 1? –

+1

Porque así es como podría causar un desbordamiento. Si eso realmente ocurre, significa que uno de tus números ya es grande. –

2

Hay John Regehr's paper sobre eso.

0

Casi siempre es más fácil (y con frecuencia más rápido) hacer el cálculo ingenuo y detectar si se produjo un desbordamiento. ¿Hay alguna razón específica por la cual le gustaría detectar la posibilidad antes de haciendo el cálculo?

En general, es bastante fácil detectar si se produjo un desbordamiento una vez que finaliza el cálculo. Debido a que las operaciones ingenuas son baratas, esto tampoco agrega mucho al costo de su computación si ocurriera un desbordamiento, incluso si termina necesitando rehacer algún trabajo. (Por lo general, sin embargo, ni siquiera tendrá que hacer eso).

He aquí un ejemplo (muy) simple: si agrego dos números de 64 bits sin firmar, puedo verificar el desbordamiento comparando la suma con cualquiera de los sumandos, si es más pequeño, que ocurre un desbordamiento. Por lo tanto, detectar el desbordamiento después de la computación requiere solo una comparación única (de hecho, es muy barato).

+0

Su ejemplo solo es verdadero en el caso de operandos sin firmar, no es válido en el caso general. –

+0

Y el comportamiento del desbordamiento firmado no está definido. –

+0

@Keith: para tipos primitivos, por supuesto. El OP está hablando de implementar un tipo de precisión arbitraria. Él debe ser capaz de manejar el desbordamiento para hacer crecer la representación (¡y así evitar el desbordamiento!). –

Cuestiones relacionadas