summaryrefslogtreecommitdiff
path: root/math64.c
diff options
context:
space:
mode:
authorPedro F. Giffuni <pfg@FreeBSD.org>2015-05-12 03:27:06 +0000
committerPedro F. Giffuni <pfg@FreeBSD.org>2015-05-12 03:27:06 +0000
commitf4e75c6395310fa4b119d3eaa9a4a9f8913df200 (patch)
tree2b015c205d81fa2431f0c36d7d9e903088a56d1c /math64.c
parentbe98e1ae3decabdd852fbe6496166aaa9acfbf9e (diff)
Notes
Diffstat (limited to 'math64.c')
-rw-r--r--math64.c559
1 files changed, 0 insertions, 559 deletions
diff --git a/math64.c b/math64.c
deleted file mode 100644
index 016541d998cda..0000000000000
--- a/math64.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*******************************************************************
-** m a t h 6 4 . c
-** Forth Inspired Command Language - 64 bit math support routines
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 25 January 1998
-** Rev 2.03: Support for 128 bit DP math. This file really ouught to
-** be renamed!
-** $Id: math64.c,v 1.6 2001-05-16 07:56:16-07 jsadler Exp jsadler $
-*******************************************************************/
-/*
-** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
-** All rights reserved.
-**
-** Get the latest Ficl release at http://ficl.sourceforge.net
-**
-** I am interested in hearing from anyone who uses ficl. If you have
-** a problem, a success story, a defect, an enhancement request, or
-** if you would like to contribute to the ficl release, please
-** contact me by email at the address above.
-**
-** L I C E N S E and D I S C L A I M E R
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-**
-** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-** SUCH DAMAGE.
-*/
-
-#include "ficl.h"
-#include "math64.h"
-
-
-/**************************************************************************
- m 6 4 A b s
-** Returns the absolute value of an DPINT
-**************************************************************************/
-DPINT m64Abs(DPINT x)
-{
- if (m64IsNegative(x))
- x = m64Negate(x);
-
- return x;
-}
-
-
-/**************************************************************************
- m 6 4 F l o o r e d D i v I
-**
-** FROM THE FORTH ANS...
-** Floored division is integer division in which the remainder carries
-** the sign of the divisor or is zero, and the quotient is rounded to
-** its arithmetic floor. Symmetric division is integer division in which
-** the remainder carries the sign of the dividend or is zero and the
-** quotient is the mathematical quotient rounded towards zero or
-** truncated. Examples of each are shown in tables 3.3 and 3.4.
-**
-** Table 3.3 - Floored Division Example
-** Dividend Divisor Remainder Quotient
-** -------- ------- --------- --------
-** 10 7 3 1
-** -10 7 4 -2
-** 10 -7 -4 -2
-** -10 -7 -3 1
-**
-**
-** Table 3.4 - Symmetric Division Example
-** Dividend Divisor Remainder Quotient
-** -------- ------- --------- --------
-** 10 7 3 1
-** -10 7 -3 -1
-** 10 -7 3 -1
-** -10 -7 -3 1
-**************************************************************************/
-INTQR m64FlooredDivI(DPINT num, FICL_INT den)
-{
- INTQR qr;
- UNSQR uqr;
- int signRem = 1;
- int signQuot = 1;
-
- if (m64IsNegative(num))
- {
- num = m64Negate(num);
- signQuot = -signQuot;
- }
-
- if (den < 0)
- {
- den = -den;
- signRem = -signRem;
- signQuot = -signQuot;
- }
-
- uqr = ficlLongDiv(m64CastIU(num), (FICL_UNS)den);
- qr = m64CastQRUI(uqr);
- if (signQuot < 0)
- {
- qr.quot = -qr.quot;
- if (qr.rem != 0)
- {
- qr.quot--;
- qr.rem = den - qr.rem;
- }
- }
-
- if (signRem < 0)
- qr.rem = -qr.rem;
-
- return qr;
-}
-
-
-/**************************************************************************
- m 6 4 I s N e g a t i v e
-** Returns TRUE if the specified DPINT has its sign bit set.
-**************************************************************************/
-int m64IsNegative(DPINT x)
-{
- return (x.hi < 0);
-}
-
-
-/**************************************************************************
- m 6 4 M a c
-** Mixed precision multiply and accumulate primitive for number building.
-** Multiplies DPUNS u by FICL_UNS mul and adds FICL_UNS add. Mul is typically
-** the numeric base, and add represents a digit to be appended to the
-** growing number.
-** Returns the result of the operation
-**************************************************************************/
-DPUNS m64Mac(DPUNS u, FICL_UNS mul, FICL_UNS add)
-{
- DPUNS resultLo = ficlLongMul(u.lo, mul);
- DPUNS resultHi = ficlLongMul(u.hi, mul);
- resultLo.hi += resultHi.lo;
- resultHi.lo = resultLo.lo + add;
-
- if (resultHi.lo < resultLo.lo)
- resultLo.hi++;
-
- resultLo.lo = resultHi.lo;
-
- return resultLo;
-}
-
-
-/**************************************************************************
- m 6 4 M u l I
-** Multiplies a pair of FICL_INTs and returns an DPINT result.
-**************************************************************************/
-DPINT m64MulI(FICL_INT x, FICL_INT y)
-{
- DPUNS prod;
- int sign = 1;
-
- if (x < 0)
- {
- sign = -sign;
- x = -x;
- }
-
- if (y < 0)
- {
- sign = -sign;
- y = -y;
- }
-
- prod = ficlLongMul(x, y);
- if (sign > 0)
- return m64CastUI(prod);
- else
- return m64Negate(m64CastUI(prod));
-}
-
-
-/**************************************************************************
- m 6 4 N e g a t e
-** Negates an DPINT by complementing and incrementing.
-**************************************************************************/
-DPINT m64Negate(DPINT x)
-{
- x.hi = ~x.hi;
- x.lo = ~x.lo;
- x.lo ++;
- if (x.lo == 0)
- x.hi++;
-
- return x;
-}
-
-
-/**************************************************************************
- m 6 4 P u s h
-** Push an DPINT onto the specified stack in the order required
-** by ANS Forth (most significant cell on top)
-** These should probably be macros...
-**************************************************************************/
-void i64Push(FICL_STACK *pStack, DPINT i64)
-{
- stackPushINT(pStack, i64.lo);
- stackPushINT(pStack, i64.hi);
- return;
-}
-
-void u64Push(FICL_STACK *pStack, DPUNS u64)
-{
- stackPushINT(pStack, u64.lo);
- stackPushINT(pStack, u64.hi);
- return;
-}
-
-
-/**************************************************************************
- m 6 4 P o p
-** Pops an DPINT off the stack in the order required by ANS Forth
-** (most significant cell on top)
-** These should probably be macros...
-**************************************************************************/
-DPINT i64Pop(FICL_STACK *pStack)
-{
- DPINT ret;
- ret.hi = stackPopINT(pStack);
- ret.lo = stackPopINT(pStack);
- return ret;
-}
-
-DPUNS u64Pop(FICL_STACK *pStack)
-{
- DPUNS ret;
- ret.hi = stackPopINT(pStack);
- ret.lo = stackPopINT(pStack);
- return ret;
-}
-
-
-/**************************************************************************
- m 6 4 S y m m e t r i c D i v
-** Divide an DPINT by a FICL_INT and return a FICL_INT quotient and a
-** FICL_INT remainder. The absolute values of quotient and remainder are not
-** affected by the signs of the numerator and denominator (the operation
-** is symmetric on the number line)
-**************************************************************************/
-INTQR m64SymmetricDivI(DPINT num, FICL_INT den)
-{
- INTQR qr;
- UNSQR uqr;
- int signRem = 1;
- int signQuot = 1;
-
- if (m64IsNegative(num))
- {
- num = m64Negate(num);
- signRem = -signRem;
- signQuot = -signQuot;
- }
-
- if (den < 0)
- {
- den = -den;
- signQuot = -signQuot;
- }
-
- uqr = ficlLongDiv(m64CastIU(num), (FICL_UNS)den);
- qr = m64CastQRUI(uqr);
- if (signRem < 0)
- qr.rem = -qr.rem;
-
- if (signQuot < 0)
- qr.quot = -qr.quot;
-
- return qr;
-}
-
-
-/**************************************************************************
- m 6 4 U M o d
-** Divides a DPUNS by base (an UNS16) and returns an UNS16 remainder.
-** Writes the quotient back to the original DPUNS as a side effect.
-** This operation is typically used to convert an DPUNS to a text string
-** in any base. See words.c:numberSignS, for example.
-** Mechanics: performs 4 ficlLongDivs, each of which produces 16 bits
-** of the quotient. C does not provide a way to divide an FICL_UNS by an
-** UNS16 and get an FICL_UNS quotient (ldiv is closest, but it's signed,
-** unfortunately), so I've used ficlLongDiv.
-**************************************************************************/
-#if (BITS_PER_CELL == 32)
-
-#define UMOD_SHIFT 16
-#define UMOD_MASK 0x0000ffff
-
-#elif (BITS_PER_CELL == 64)
-
-#define UMOD_SHIFT 32
-#define UMOD_MASK 0x00000000ffffffff
-
-#endif
-
-UNS16 m64UMod(DPUNS *pUD, UNS16 base)
-{
- DPUNS ud;
- UNSQR qr;
- DPUNS result;
-
- result.hi = result.lo = 0;
-
- ud.hi = 0;
- ud.lo = pUD->hi >> UMOD_SHIFT;
- qr = ficlLongDiv(ud, (FICL_UNS)base);
- result.hi = qr.quot << UMOD_SHIFT;
-
- ud.lo = (qr.rem << UMOD_SHIFT) | (pUD->hi & UMOD_MASK);
- qr = ficlLongDiv(ud, (FICL_UNS)base);
- result.hi |= qr.quot & UMOD_MASK;
-
- ud.lo = (qr.rem << UMOD_SHIFT) | (pUD->lo >> UMOD_SHIFT);
- qr = ficlLongDiv(ud, (FICL_UNS)base);
- result.lo = qr.quot << UMOD_SHIFT;
-
- ud.lo = (qr.rem << UMOD_SHIFT) | (pUD->lo & UMOD_MASK);
- qr = ficlLongDiv(ud, (FICL_UNS)base);
- result.lo |= qr.quot & UMOD_MASK;
-
- *pUD = result;
-
- return (UNS16)(qr.rem);
-}
-
-
-/**************************************************************************
-** Contributed by
-** Michael A. Gauland gaulandm@mdhost.cse.tek.com
-**************************************************************************/
-#if PORTABLE_LONGMULDIV != 0
-/**************************************************************************
- m 6 4 A d d
-**
-**************************************************************************/
-DPUNS m64Add(DPUNS x, DPUNS y)
-{
- DPUNS result;
- int carry;
-
- result.hi = x.hi + y.hi;
- result.lo = x.lo + y.lo;
-
-
- carry = ((x.lo | y.lo) & CELL_HI_BIT) && !(result.lo & CELL_HI_BIT);
- carry |= ((x.lo & y.lo) & CELL_HI_BIT);
-
- if (carry)
- {
- result.hi++;
- }
-
- return result;
-}
-
-
-/**************************************************************************
- m 6 4 S u b
-**
-**************************************************************************/
-DPUNS m64Sub(DPUNS x, DPUNS y)
-{
- DPUNS result;
-
- result.hi = x.hi - y.hi;
- result.lo = x.lo - y.lo;
-
- if (x.lo < y.lo)
- {
- result.hi--;
- }
-
- return result;
-}
-
-
-/**************************************************************************
- m 6 4 A S L
-** 64 bit left shift
-**************************************************************************/
-DPUNS m64ASL( DPUNS x )
-{
- DPUNS result;
-
- result.hi = x.hi << 1;
- if (x.lo & CELL_HI_BIT)
- {
- result.hi++;
- }
-
- result.lo = x.lo << 1;
-
- return result;
-}
-
-
-/**************************************************************************
- m 6 4 A S R
-** 64 bit right shift (unsigned - no sign extend)
-**************************************************************************/
-DPUNS m64ASR( DPUNS x )
-{
- DPUNS result;
-
- result.lo = x.lo >> 1;
- if (x.hi & 1)
- {
- result.lo |= CELL_HI_BIT;
- }
-
- result.hi = x.hi >> 1;
- return result;
-}
-
-
-/**************************************************************************
- m 6 4 O r
-** 64 bit bitwise OR
-**************************************************************************/
-DPUNS m64Or( DPUNS x, DPUNS y )
-{
- DPUNS result;
-
- result.hi = x.hi | y.hi;
- result.lo = x.lo | y.lo;
-
- return result;
-}
-
-
-/**************************************************************************
- m 6 4 C o m p a r e
-** Return -1 if x < y; 0 if x==y, and 1 if x > y.
-**************************************************************************/
-int m64Compare(DPUNS x, DPUNS y)
-{
- int result;
-
- if (x.hi > y.hi)
- {
- result = +1;
- }
- else if (x.hi < y.hi)
- {
- result = -1;
- }
- else
- {
- /* High parts are equal */
- if (x.lo > y.lo)
- {
- result = +1;
- }
- else if (x.lo < y.lo)
- {
- result = -1;
- }
- else
- {
- result = 0;
- }
- }
-
- return result;
-}
-
-
-/**************************************************************************
- f i c l L o n g M u l
-** Portable versions of ficlLongMul and ficlLongDiv in C
-** Contributed by:
-** Michael A. Gauland gaulandm@mdhost.cse.tek.com
-**************************************************************************/
-DPUNS ficlLongMul(FICL_UNS x, FICL_UNS y)
-{
- DPUNS result = { 0, 0 };
- DPUNS addend;
-
- addend.lo = y;
- addend.hi = 0; /* No sign extension--arguments are unsigned */
-
- while (x != 0)
- {
- if ( x & 1)
- {
- result = m64Add(result, addend);
- }
- x >>= 1;
- addend = m64ASL(addend);
- }
- return result;
-}
-
-
-/**************************************************************************
- f i c l L o n g D i v
-** Portable versions of ficlLongMul and ficlLongDiv in C
-** Contributed by:
-** Michael A. Gauland gaulandm@mdhost.cse.tek.com
-**************************************************************************/
-UNSQR ficlLongDiv(DPUNS q, FICL_UNS y)
-{
- UNSQR result;
- DPUNS quotient;
- DPUNS subtrahend;
- DPUNS mask;
-
- quotient.lo = 0;
- quotient.hi = 0;
-
- subtrahend.lo = y;
- subtrahend.hi = 0;
-
- mask.lo = 1;
- mask.hi = 0;
-
- while ((m64Compare(subtrahend, q) < 0) &&
- (subtrahend.hi & CELL_HI_BIT) == 0)
- {
- mask = m64ASL(mask);
- subtrahend = m64ASL(subtrahend);
- }
-
- while (mask.lo != 0 || mask.hi != 0)
- {
- if (m64Compare(subtrahend, q) <= 0)
- {
- q = m64Sub( q, subtrahend);
- quotient = m64Or(quotient, mask);
- }
- mask = m64ASR(mask);
- subtrahend = m64ASR(subtrahend);
- }
-
- result.quot = quotient.lo;
- result.rem = q.lo;
- return result;
-}
-
-#endif
-