aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2012-01-09 05:46:16 -0800
committerLev Walkin <vlm@lionet.info>2012-01-09 06:02:29 -0800
commite8727ec286439b8a00d0b312f156244f8fd88764 (patch)
tree6c446bb89dc339b9b18118ef2d6ba6477f1e0451
parent5fda7d5e9324f13608f1071e7ee3eff0e4e4d905 (diff)
Check binary encodings of a Real value
-rw-r--r--skeletons/tests/check-REAL.c125
1 files changed, 114 insertions, 11 deletions
diff --git a/skeletons/tests/check-REAL.c b/skeletons/tests/check-REAL.c
index db418f06..adad56e7 100644
--- a/skeletons/tests/check-REAL.c
+++ b/skeletons/tests/check-REAL.c
@@ -172,9 +172,7 @@ check_ber_buffer_twoway(double d, const char *sample, const char *canonical_samp
*/
rn.buf = inbuf;
rn.size = insize;
-printf("%03d %f === %s %s\n", lineno, d, sample, canonical_sample);
asn_REAL2double(&rn, &val);
-printf("%03d %f/%f %s %s\n", lineno, val, d, sample, canonical_sample);
if(isnan(val)) assert(isnan(d));
if(isnan(d)) assert(isnan(val));
if(!isnan(val) && !isnan(d)) {
@@ -188,15 +186,6 @@ printf("%03d %f/%f %s %s\n", lineno, val, d, sample, canonical_sample);
memset(&rn, 0, sizeof(rn));
ret = asn_double2REAL(&rn, d);
assert(ret == 0);
- uint8_t *p, *end;
- printf("received as: [");
- for(p = rn.buf, end = p + rn.size; p < end; p++)
- printf("%02x", *p);
- printf("]\n");
- printf("received as: [");
- for(p = outbuf, end = p + outsize; p < end; p++)
- printf("%02x", *p);
- printf("]\n");
if(rn.size != outsize) {
printf("Encoded %f into %d expected %ld\n",
d, (int)rn.size, outsize);
@@ -248,6 +237,103 @@ check_ber_buffer_oneway(double d, const char *sample, const char *canonical_samp
check_str_representation(val, sample, canonical_sample, lineno);
}
+/*
+ * 8.5.7 Verify binary encoding, two-way.
+ */
+static void
+check_ber_857_encoding(int base, int sign, int scaling_factor, int exponent, int mantissa) {
+ uint8_t buf[100];
+ uint8_t *b = buf;
+ int explen, mantlen;
+ REAL_t rn;
+ static REAL_t rn_check;
+ double d;
+ double verify;
+ int baseF = 0;
+ int ret;
+
+#define BIT(b) (1<<(b - 1))
+
+ switch(base) {
+ case 0: baseF = 1; break;
+ case 1: baseF = 3; break;
+ case 2: baseF = 4; break;
+ default: assert(base >= 0 && base <= 2);
+ }
+
+ if(exponent >= -128 && exponent <= 127) {
+ explen = 1;
+ } else {
+ assert(exponent > -60000 && exponent < 60000);
+ explen = 2;
+ }
+
+ if(mantissa == 0) {
+ mantlen = 0;
+ } else if(mantissa >= 0 && mantissa <= 255) {
+ mantlen = 1;
+ } else if(mantissa >= 0 && mantissa <= 65535) {
+ mantlen = 2;
+ } else {
+ assert(mantissa >= 0 && mantissa <= 256 * 65536);
+ mantlen = 3;
+ }
+
+ *b = BIT(8) | (sign ? BIT(7) : 0);
+ *b |= (base & 0x03) << 4; /* 8.5.7.2 */
+ *b |= (scaling_factor & 0x03) << 2; /* 8.5.7.3 */
+ *b |= ((explen - 1) & 0x03); /* 8.5.7.4 */
+ b++;
+ switch(explen) {
+ case 2: *b++ = (int8_t)(exponent >> 8);
+ case 1: *b++ = (int8_t)exponent;
+ }
+ switch(mantlen) {
+ case 3: *b++ = (mantissa >> 16) & 0xff;
+ case 2: *b++ = (mantissa >> 8) & 0xff;
+ case 1: *b++ = (mantissa & 0xff);
+ }
+
+ verify = (sign ? -1.0 : 1.0) * ldexp(mantissa, exponent * baseF + scaling_factor);
+
+ /* Verify than encoding of this double value round-trips */
+ if(!isinf(verify)) {
+ d = verify;
+ verify = 0.0;
+ ret = asn_double2REAL(&rn_check, d);
+ assert(ret == 0);
+ ret = asn_REAL2double(&rn_check, &verify);
+ assert(ret == 0);
+ assert(d == verify);
+
+ /* Verify with a slight non-friendly offset. Not too easy. */
+ d = verify - 0.13;
+ verify = 0.0;
+ ret = asn_double2REAL(&rn_check, d);
+ assert(ret == 0);
+ ret = asn_REAL2double(&rn_check, &verify);
+ assert(ret == 0);
+ assert(ret == 0);
+ assert(d == verify);
+ }
+
+ verify = (sign ? -1.0 : 1.0) * ldexp(mantissa, exponent * baseF + scaling_factor);
+
+ rn.buf = buf;
+ rn.size = b - buf;
+ ret = asn_REAL2double(&rn, &d);
+ if(!isinf(verify) && (ret != 0 || d != verify)) {
+ printf("Converting B=%d, S=%d, F=%d, E=%d/%d, M=%d/%d\n", (1 << baseF), sign, scaling_factor, exponent, explen, mantissa, mantlen);
+ printf("Verify: %e\n", verify);
+ uint8_t *p;
+ printf("received as: [");
+ for(p = buf; p < b; p++) printf("%02x", *p);
+ printf("]\n");
+ assert(ret == 0);
+ printf("Converted: %e\n", d);
+ assert(d == verify);
+ }
+}
static void
check_ber_encoding() {
@@ -483,6 +569,23 @@ check_ber_encoding() {
} /* for(comma symbol) */
}
+ /* Scan through the range of bits, construct the valid base-2 numbers, and
+ * try two-way conversion with them */
+ {
+ int base, sign, scaling_factor, exponent, mantissa;
+ for(base = 0; base <= 2; base++) {
+ for(sign = 0; sign <= 1; sign++) {
+ for(scaling_factor = 0; scaling_factor <= 3; scaling_factor++) {
+ for(exponent = -1000; exponent < 1000; exponent += (exponent > -990 && exponent < 990) ? 100 : 1) {
+ for(mantissa = 0; mantissa < 66000; mantissa += (mantissa > 300 && mantissa < 65400) ? 100 : 1) {
+ check_ber_857_encoding(base, sign, scaling_factor, exponent, mantissa);
+ }
+ }
+ }
+ }
+ }
+ }
+
{
uint8_t b_1_0[] =
{ 0x80, 0xcc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };