gawk-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gawk-diffs] [SCM] gawk branch, long-double, updated. 5f4dbd4819a7dae080


From: John Haque
Subject: [gawk-diffs] [SCM] gawk branch, long-double, updated. 5f4dbd4819a7dae080c6ff4833a06cf1ca8d502c
Date: Tue, 15 Jan 2013 10:57:14 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gawk".

The branch, long-double has been updated
       via  5f4dbd4819a7dae080c6ff4833a06cf1ca8d502c (commit)
      from  e8561893a3ca3f7cee6ca23e4361abbb510502bb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.sv.gnu.org/cgit/gawk.git/commit/?id=5f4dbd4819a7dae080c6ff4833a06cf1ca8d502c

commit 5f4dbd4819a7dae080c6ff4833a06cf1ca8d502c
Author: John Haque <address@hidden>
Date:   Tue Jan 15 04:55:45 2013 -0600

    Added file misc/sprintf_0Lf.awk, fixed bug in misc/fp_math.awk.

diff --git a/misc/fp_math.awk b/misc/fp_math.awk
index 634d128..51583fa 100644
--- a/misc/fp_math.awk
+++ b/misc/fp_math.awk
@@ -137,13 +137,17 @@ function fp_atan2(y, x,   \
 
 #
 #      Collect two terms in each iteration for the Taylor series:
-#              sin(x) = (x - x^3/3!) + (x^5/7! - x^9/9!) + ...
+#              sin(x) = (x - x^3/3!) + (x^5/5! - x^7/7!) + ...
 #
 
 function taylor_sin(x, \
                i, fact, xpow2, xpow_odd, sum, term, err)
 {
-       # XXX: this assumes x >= 0
+       # this assumes x >= 0
+       if (x < 0) {
+               print "taylor_sin: received x < 0 ! " > "/dev/stderr"
+               exit(1)
+       }
 
        if (x == 0)
                return x
@@ -208,7 +212,7 @@ function taylor_cos(x,      \
 
 #
 # For 0 <= x <= PI/4, using Taylor series approximation for sin(x):
-#      x - x^3/5! + x^5/7! - ...
+#      x - x^3/3! + x^5/5! - ...
 #
 # for PI/4 < x <= PI/2, use identity sin(x) = cos(PI/2 - x).
 #
@@ -279,11 +283,6 @@ function fp_cos(x, \
        return cv
 }
 
-function fp_atan2(y, x)
-{
-       return euler_atan2(y, x)
-}
-
 function isinf(x)
 {
        x = + x 
diff --git a/misc/sprintf_0Lf.awk b/misc/sprintf_0Lf.awk
new file mode 100644
index 0000000..d504604
--- /dev/null
+++ b/misc/sprintf_0Lf.awk
@@ -0,0 +1,172 @@
+#
+#      sprintf_0Lf.awk -- format integers stored as long doubles and
+#      don't have %Lf in (s)printf.
+#      This test script handles integers < 2^64 even with 128-bit long doubles.
+#      Requires both -M (for verification) and -B
+#      Usage: echo "2^63 + 2^54 + 2^13" | ./gawk -B -f misc/sprintf_0Lf.awk
+#
+
+BEGIN {
+       # 113 for 128-bit long double, but can only get 64-bit ints.
+       LDBL_MANT_DIG = 64
+       POW2[0] = 1
+       for (i = 1; i <= LDBL_MANT_DIG; i++)
+               POW2[i] = POW2[i - 1] * 2       
+}
+
+{
+       #
+       # Compare apples to apples, setting PREC=64; With real 128-bit long 
doubles,
+       # one probably should use PREC=quad or 113.
+       #
+
+       eval = sprintf("./gawk -M -vPREC=64 'BEGIN { printf(\"%%0.34e\", %s); 
print \"\";\
+               printf(\"%%020d\", %s); print \"\";\
+               printf(\"%%d\", int(%s) == %s + 0); print \"\"}'", $0, $0, $0, 
$0)
+       eval | getline num
+       eval | getline ap_intval
+       eval | getline ap_isint
+       close(eval)
+
+       pnum = num + 0
+       sign = ""
+       if (pnum < 0) {
+               pnum = -pnum
+               sign = "-"
+       }
+
+       isint = isinteger(pnum, W)
+       if (isint) {
+               if (! ap_isint)
+                       print "!!!!!!!!!MPFR says it is not an integer!!!!!!!!!"
+               printf("%s (%s) is an integer\n", $0, sprintf("%0.34e", num))
+               printf("sprintf_int64  :%c%s\n", sign, sprintf_int64(W))
+               printf("arbitrary-prec :%s\n", ap_intval)
+               printf("LDBL %%0.Lf     :%c%020d\n", sign, pnum)        # or 
garbage if no %Lf
+       } else {
+               if (ap_isint)
+                       print "!!!!!!!!!MPFR says it is an integer!!!!!!!!!"
+               printf("%s (%s) is not an integer\n", $0, sprintf("%0.34e", 
num))
+       }
+}
+
+
+function sprintf_int64(d,      d0, d1, d2, d3, d4, q, k)
+{
+       #
+       # Binary to Decimal Conversion in Limited Precision - Douglas B. Jones
+       #       URL: homepage.cs.uiowa.edu/~jones/bcd/decimal.html
+       #
+
+       if (DEBUG) {
+               for (k = 0; k < 4; k++) {
+                       if (d[k] > 65535)
+                               printf("d[%d] > 65535, this ain't right\n", k)
+               }
+               print "(16 MSB bits first):", d[3], "|", d[2], "|", d[1], "|", 
d[0]
+       }
+
+        d0 = 656 * d[3] + 7296 * d[2] + 5536 * d[1] + d[0];
+
+        q = int(d0 / 10000);   # int() may call floorl(), but double version 
is good enough
+                               # in this case. This is only a consideration in 
the awk code,
+                               # not in the C translation.
+
+        d0 = d0 - q * 10000;   # not using % operator, may not have fmodl()
+
+        d1 = q + 7671 * d[3] + 9496 * d[2] + 6 * d[1];
+        q = int(d1 / 10000);
+        d1 = d1 - q * 10000;
+
+        d2 = q + 4749 * d[3] + 42 * d[2];
+        q = int(d2 / 10000);
+        d2 = d2 - q * 10000;
+
+        d3 = q + 281 * d[3];
+        q = int(d3 / 10000);
+        d3 = d3 - q * 10000;
+
+        d4 = q;
+       return sprintf("%4.4u%4.4u%4.4u%4.4u%4.4u", \
+                       d4, d3, d2, d1, d0);    # don't need %Lf support here
+}
+
+
+function isinteger(x, D,       j, low, high)
+{
+       # Assume x >= 0
+
+       #
+       # XXX: x >= 2^LDBL_MANT_DIG
+       #       test using C-double is adequate at least in the range
+       #       2^LDBL_MANT_DIG <= x <= DBL_MAX; the integers have same
+       #       representations. Here in awk code, we simply crap out.
+       #
+
+       if (x >= POW2[LDBL_MANT_DIG]) {
+               printf("number %0.34e is too big (> %0.34e), bailing out\n", x, 
2^64 - 1)
+               exit(1);
+       }
+
+       D[0] = D[1] = D[2] = D[3] = 0
+ 
+       # binary search
+       high = LDBL_MANT_DIG - 1
+       while (x >= 2) {
+               low = 0
+               while (low <= high) {
+                       mid = int((low + high) / 2)
+                       if (x < POW2[mid])
+                               high = mid - 1
+                       else
+                               low = mid + 1
+               }
+
+               if (x < POW2[low]) {
+                       x -= POW2[low - 1]
+
+                       #
+                       # Easier to seperate the 64 bits into 16-bit chunks now
+                       # then doing bit fiddling later.
+                       #       | D[3] | D[2] | D[1] | D[0] |
+                       #       |<------- x (64 bits) ----->|
+                       #
+
+                       if (low <= 16) { D[0] += POW2[low - 1] }
+                       else if (low <= 32) { D[1] += POW2[low - 17] }
+                       else if (low <= 48) { D[2] += POW2[low - 33] }
+                       else { D[3] += POW2[low - 49] }
+               }
+
+               high = low
+       }
+
+#
+#      # XXX -- O(n^2) vs. O(n * log(n))  -- how much do we really gain?
+#      #       Consider extra additions and divisions, but less # of < 
comparisons.
+#
+#      while (x >= 2) {
+#              for (j = 1; j <= LDBL_MANT_DIG; j++) {
+#                      if (x < POW2[j]) {
+#                              x -= POW2[j - 1]
+#                              break
+#                      }
+#              }
+#      }
+#
+
+       if (x == 0)
+               return 1;
+       if (x == 1) {
+               if (and(D[0], 1)) {
+                       ######## XXX: MAYBE ADDING A SECOND TIME ??? #######
+                       print "Opps! there may be a bug in code! D[0] = ", D[0] 
> "/dev/stderr"
+                       exit(1)
+               }
+
+               D[0]++
+               return 1
+       }
+
+       return 0
+} 

-----------------------------------------------------------------------

Summary of changes:
 misc/fp_math.awk     |   15 ++---
 misc/sprintf_0Lf.awk |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 8 deletions(-)
 create mode 100644 misc/sprintf_0Lf.awk


hooks/post-receive
-- 
gawk



reply via email to

[Prev in Thread] Current Thread [Next in Thread]