summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/tp6tod.c
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/tp6tod.c')
-rwxr-xr-xreference/C/CONTRIB/SNIP/tp6tod.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/tp6tod.c b/reference/C/CONTRIB/SNIP/tp6tod.c
new file mode 100755
index 0000000..cdc9154
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/tp6tod.c
@@ -0,0 +1,74 @@
+/*
+** Convert Turbo Pascal 6-byte reals to C double format
+** Written by Thad Smith III, Boulder, CO. 12/91
+** Tested on TC 2.01, BC++ 2.0/3.0, QC 2.50, Power C 2.0.1, ZTC 3.0
+** Contributed to the Public Domain.
+*/
+
+#include <math.h>
+#include <string.h>
+#ifdef TEST
+ #include <stdio.h>
+#endif
+
+/*
+** Specify packed structures.
+** Note: This may not work on some compilers.
+*/
+
+#if __TURBOC__ > 0x0201
+ #pragma option -a-
+#elif defined __ZTC__
+ #pragma ZTC align 1
+#else /* MSC, WATCOM */
+ #pragma pack(1)
+#endif
+
+double tp6_to_double(const unsigned char *tp6)
+{
+ struct {
+ unsigned char be ; /* biased exponent */
+ unsigned int v1 ; /* lower 16 bits of mantissa */
+ unsigned int v2 ; /* next 16 bits of mantissa */
+ unsigned int v3:7; /* upper 7 bits of mantissa */
+ unsigned int s :1; /* sign bit */
+ } real;
+
+ memcpy (&real, tp6, 6);
+ if (real.be == 0)
+ return 0.0;
+ return (((((128 +real.v3) * 65536.0) + real.v2) * 65536.0 + real.v1) *
+ ldexp ((real.s? -1.0: 1.0), real.be - (129+39)));
+}
+
+#ifdef TEST
+
+/*
+** This test program reads 6-byte values, one per line, in
+** 12-digit hexadecimal format from stdin, converts to a double,
+** then prints it.
+*/
+
+void main(void)
+{
+ unsigned char c[6];
+ int buf[6];
+ int i, n;
+
+ for (;;)
+ {
+ n = scanf (" %2x%2x%2x%2x%2x%2x", &buf[0], &buf[1], &buf[2],
+ &buf[3], &buf[4], &buf[5]);
+ if (n <= 0)
+ break;
+ for (i=0; i < 6; i++)
+ {
+ c [i] = buf[i];
+ printf ("%2.2x", buf[i]);
+ }
+ printf (" = %lg\n", tp6_to_double (c));
+ }
+ return 0;
+}
+
+#endif