Commit 8ca13c8a authored by Lev Walkin's avatar Lev Walkin

test subnormals

parent 104af19d
......@@ -137,9 +137,16 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key)
* Transform the "[-]d.dddE+-dd" output into "[-]d.dddE[-]d"
* Check that snprintf() constructed the output correctly.
*/
char *dot, *E;
char *dot;
char *end = buf + buflen;
char *last_zero;
char *prev_zero;
char *s;
enum {
LZSTATE_NOTHING,
LZSTATE_SEEN_ZERO
} lz_state = LZSTATE_NOTHING;
dot = (buf[0] == 0x2d /* '-' */) ? (buf + 2) : (buf + 1);
if(*dot >= 0x30) {
......@@ -149,51 +156,67 @@ REAL__dump(double d, int canonical, asn_app_consume_bytes_f *cb, void *app_key)
}
*dot = 0x2e; /* Replace possible comma */
for(last_zero = dot + 2, E = dot; dot < end; E++) {
if(*E == 0x45) {
char *expptr = ++E;
char *s = expptr;
int sign;
if(*expptr == 0x2b /* '+' */) {
/* Skip the "+" */
buflen -= 1;
sign = 0;
} else {
sign = 1;
s++;
}
expptr++;
if(expptr > end) {
if(buf != local_buf) FREEMEM(buf);
errno = EINVAL;
return -1;
}
if(*expptr == 0x30) {
buflen--;
expptr++;
}
if(*last_zero == 0x30) {
*last_zero = 0x45; /* E */
buflen -= s - (last_zero + 1);
s = last_zero + 1;
if(sign) {
*s++ = 0x2d /* '-' */;
buflen++;
}
}
for(; expptr <= end; s++, expptr++)
*s = *expptr;
break;
} else if(*E == 0x30) {
if(*last_zero != 0x30)
last_zero = E;
}
}
if(E == end) {
for(prev_zero = last_zero = s = dot + 2; s < end; s++) {
switch(*s) {
case 0x45: /* 'E' */
if(lz_state == LZSTATE_SEEN_ZERO)
last_zero = prev_zero;
break;
case 0x30: /* '0' */
if(lz_state == LZSTATE_NOTHING)
prev_zero = s;
lz_state = LZSTATE_SEEN_ZERO;
continue;
default:
lz_state = LZSTATE_NOTHING;
continue;
}
break;
}
if(s == end) {
if(buf != local_buf) FREEMEM(buf);
errno = EINVAL;
return -1; /* No promised E */
}
assert(*s == 0x45);
{
char *E = s;
char *expptr = ++E;
char *s = expptr;
int sign;
if(*expptr == 0x2b /* '+' */) {
/* Skip the "+" */
buflen -= 1;
sign = 0;
} else {
sign = 1;
s++;
}
expptr++;
if(expptr > end) {
if(buf != local_buf) FREEMEM(buf);
errno = EINVAL;
return -1;
}
if(*expptr == 0x30) {
buflen--;
expptr++;
}
if(*last_zero == 0x30) {
*last_zero = 0x45; /* E */
buflen -= s - (last_zero + 1);
s = last_zero + 1;
if(sign) {
*s++ = 0x2d /* '-' */;
buflen++;
}
}
for(; expptr <= end; s++, expptr++)
*s = *expptr;
}
} else {
/*
* Remove trailing zeros.
......
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <REAL.h>
......@@ -45,14 +46,14 @@ check_str_representation(double d, const char *sample, const char *canonical_sam
s1 = d2s(d, 1);
if(sample) {
printf("%03d: Checking %f->[\"%s\"] against [\"%s\"]%s\n",
printf("%03d: Checking %g->[\"%s\"] against [\"%s\"]%s\n",
lineno, d, s0, sample,
canonical_sample ? " (canonical follows...)" : ""
);
assert(!strcmp(s0, sample));
}
if(canonical_sample) {
printf("%03d: Checking %f->[\"%s\"] against [\"%s\"] (canonical)\n",
printf("%03d: Checking %g->[\"%s\"] against [\"%s\"] (canonical)\n",
lineno, d, s1, canonical_sample);
assert(!strcmp(s1, canonical_sample));
}
......@@ -655,7 +656,20 @@ main() {
check(&rn,-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
check(&rn,-3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
check(&rn, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333, 0, 0);
check(&rn, -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 0, 0);
check(&rn, 0.25, "0.25", "2.5E-1");
check(&rn, -0.25, "-0.25", "-2.5E-1");
check(&rn, 0.03, "0.03", "3.0E-2");
check(&rn, -0.03, "-0.03", "-3.0E-2");
check(&rn, 4.01E-50, "0.0", "4.01E-50");
check(&rn, -4.01E-50, "-0.0", "-4.01E-50");
check(&rn, -4.9406564584124654E-324, "-0.0", "-4.940656458412465E-324"); /* MIN */
check(&rn, DBL_MIN, "0.0", "2.225073858507201E-308"); /* MIN */
check(&rn, -DBL_MIN, "-0.0", "-2.225073858507201E-308"); /* -MIN */
check(&rn, DBL_MAX, "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0", "1.797693134862316E308"); /* MAX */
check(&rn, -DBL_MAX, "-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0", "-1.797693134862316E308"); /* MAX */
check(&rn, -DBL_TRUE_MIN, "-0.0", "-4.940656458412465E-324"); /* subnorm */
check(&rn, DBL_TRUE_MIN, "0.0", "4.940656458412465E-324"); /* subnorm */
#ifdef NAN
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment