Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/lib/math/modf.c
There are 8 other files named modf.c in the archive. Click here to see a list.
/*
** MODF.C - split floating point number into int and fractional parts
**
** (c) Copyright Ken Harrenstien 1989
**
** This code does NOT conform to the description of the modf function
** as defined in Harbison and Steele's "C: A Reference Manual",
** section 11.3.18. H&S is wrong in saying that the
** 2nd arg to "modf" is an (int *); both ANSI and BSD say it is a
** (double *). Otherwise the description is accurate.
**
** Note that this only works for normalized values. In particular, a number
** with only the sign bit set is unnormalized. Fortunately the hardware never
** generates such numbers.
*/
#include <c-env.h> /* So can see what format we're using */
#if CPU_PDP10 /* Currently PDP-10 only */
double
modf(x, iptr)
double x, *iptr; /* Note 2nd arg is ptr to double, not int! */
{
#if CENV_DFL_H /* PDP-10 hardware double precision fmt */
#asm
EXTERN $ZERO /* From CRT */
DMOVE 1,-2(17) /* Get double arg */
SKIPGE 7,1 /* Check for neg number, remember sign in 7 */
DMOVN 1,1 /* Negative, so turn it over */
CAMG 1,[201000,,0] /* Do we have an integer part? */
JRST [ SETZB 3,4 /* No, set integer part to (double) 0 */
DMOVEM 3,@-3(17) /* Store via pointer */
CAIG 7,0 /* If arg was negative, */
DMOVN 1,1 /* must return negative result. */
POPJ 17,]
CAML 1,[276000,,0] /* Do we have a fraction part? */
JRST [ CAIG 7,0 /* No, just store arg as integer part */
DMOVN 1,1
DMOVEM 1,@-3(17)
SETZB 1,2 /* And return zero fractional part! */
POPJ 17,]
/* Have both integer and fraction part. Find fraction bit mask. */
LDB 4,[331000,,1] /* Get exponent */
MOVNI 4,-200(4) /* Find -<# bits in integral part> */
MOVSI 5,400000 /* Get a sign-bit-set doubleword mask */
SETZ 6,
ASHC 5,-10(4) /* Shift mask over exponent & integer bits */
DMOVE 3,1 /* Copy positive # for integer part */
AND 3,5
AND 4,6 /* Mask out fract bits, leave integer bits */
TLZ 5,777000 /* After ensuring that exponent preserved, */
ANDCM 1,5 /* apply reverse mask to get fraction bits. */
ANDCM 2,6
JUMPL 7,[ /* If negation needed, */
DMOVNM 3,@-3(17) /* store negated integer part, and */
DMOVN 1,1 /* negate returned fractional part */
JRST .+2] /* Skip over DMOVEM */
DMOVEM 3,@-3(17) /* Store integer part */
DFAD 1,$ZERO /* and normalize returned fraction. */
/* Drop thru to return */
#endasm
#else
#error modf() not implemented for this double-precision format.
#endif
}
#endif /* CPU_PDP10 */