Home | History | Annotate | Line # | Download | only in libntp
timespecops.c revision 1.1.1.7
      1 /*	$NetBSD: timespecops.c,v 1.1.1.7 2018/04/07 00:15:57 christos Exp $	*/
      2 
      3 #include "config.h"
      4 
      5 #include "ntp_types.h"
      6 #include "ntp_fp.h"
      7 #include "timespecops.h"
      8 
      9 #include "unity.h"
     10 
     11 #include <math.h>
     12 #include <string.h>
     13 
     14 
     15 #define TEST_ASSERT_EQUAL_timespec(a, b) {				\
     16     TEST_ASSERT_EQUAL_MESSAGE(a.tv_sec, b.tv_sec, "Field tv_sec");	\
     17     TEST_ASSERT_EQUAL_MESSAGE(a.tv_nsec, b.tv_nsec, "Field tv_nsec");	\
     18 }
     19 
     20 
     21 #define TEST_ASSERT_EQUAL_l_fp(a, b) {					\
     22     TEST_ASSERT_EQUAL_MESSAGE(a.l_i, b.l_i, "Field l_i");		\
     23     TEST_ASSERT_EQUAL_UINT_MESSAGE(a.l_uf, b.l_uf, "Field l_uf");	\
     24 }
     25 
     26 
     27 static u_int32 my_tick_to_tsf(u_int32 ticks);
     28 static u_int32 my_tsf_to_tick(u_int32 tsf);
     29 
     30 
     31 // that's it...
     32 struct lfpfracdata {
     33 	long	nsec;
     34 	u_int32 frac;
     35 };
     36 
     37 
     38 void setUp(void);
     39 void test_Helpers1(void);
     40 void test_Normalise(void);
     41 void test_SignNoFrac(void);
     42 void test_SignWithFrac(void);
     43 void test_CmpFracEQ(void);
     44 void test_CmpFracGT(void);
     45 void test_CmpFracLT(void);
     46 void test_AddFullNorm(void);
     47 void test_AddFullOflow1(void);
     48 void test_AddNsecNorm(void);
     49 void test_AddNsecOflow1(void);
     50 void test_SubFullNorm(void);
     51 void test_SubFullOflow(void);
     52 void test_SubNsecNorm(void);
     53 void test_SubNsecOflow(void);
     54 void test_Neg(void);
     55 void test_AbsNoFrac(void);
     56 void test_AbsWithFrac(void);
     57 void test_Helpers2(void);
     58 void test_ToLFPbittest(void);
     59 void test_ToLFPrelPos(void);
     60 void test_ToLFPrelNeg(void);
     61 void test_ToLFPabs(void);
     62 void test_FromLFPbittest(void);
     63 void test_FromLFPrelPos(void);
     64 void test_FromLFPrelNeg(void);
     65 void test_LFProundtrip(void);
     66 void test_ToString(void);
     67 
     68 const bool	timespec_isValid(struct timespec V);
     69 struct timespec timespec_init(time_t hi, long lo);
     70 l_fp		l_fp_init(int32 i, u_int32 f);
     71 bool		AssertFpClose(const l_fp m, const l_fp n, const l_fp limit);
     72 bool		AssertTimespecClose(const struct timespec m,
     73 				    const struct timespec n,
     74 				    const struct timespec limit);
     75 
     76 
     77 //***************************MY CUSTOM FUNCTIONS***************************
     78 
     79 
     80 void
     81 setUp(void)
     82 {
     83 	init_lib();
     84 
     85 	return;
     86 }
     87 
     88 
     89 const bool
     90 timespec_isValid(struct timespec V)
     91 {
     92 
     93 	return V.tv_nsec >= 0 && V.tv_nsec < 1000000000;
     94 }
     95 
     96 
     97 struct timespec
     98 timespec_init(time_t hi, long lo)
     99 {
    100 	struct timespec V;
    101 
    102 	V.tv_sec = hi;
    103 	V.tv_nsec = lo;
    104 
    105 	return V;
    106 }
    107 
    108 
    109 l_fp
    110 l_fp_init(int32 i, u_int32 f)
    111 {
    112 	l_fp temp;
    113 
    114 	temp.l_i  = i;
    115 	temp.l_uf = f;
    116 
    117 	return temp;
    118 }
    119 
    120 
    121 bool
    122 AssertFpClose(const l_fp m, const l_fp n, const l_fp limit)
    123 {
    124 	l_fp diff;
    125 
    126 	if (L_ISGEQ(&m, &n)) {
    127 		diff = m;
    128 		L_SUB(&diff, &n);
    129 	} else {
    130 		diff = n;
    131 		L_SUB(&diff, &m);
    132 	}
    133 	if (L_ISGEQ(&limit, &diff)) {
    134 		return TRUE;
    135 	}
    136 	else {
    137 		printf("m_expr which is %s \nand\nn_expr which is %s\nare not close; diff=%susec\n",
    138 		       lfptoa(&m, 10), lfptoa(&n, 10), lfptoa(&diff, 10));
    139 		return FALSE;
    140 	}
    141 }
    142 
    143 
    144 bool
    145 AssertTimespecClose(const struct timespec m, const struct timespec n,
    146 	const struct timespec limit)
    147 {
    148 	struct timespec diff;
    149 
    150 	diff = abs_tspec(sub_tspec(m, n));
    151 	if (cmp_tspec(limit, diff) >= 0)
    152 		return TRUE;
    153 
    154 	printf("m_expr which is %lld.%09lu \nand\n"
    155 	       "n_expr which is %lld.%09lu\nare not close; diff=%lld.%09lunsec\n",
    156 	       (long long)m.tv_sec, m.tv_nsec,
    157 	       (long long)n.tv_sec, n.tv_nsec,
    158 	       (long long)diff.tv_sec, diff.tv_nsec);
    159 	return FALSE;
    160 }
    161 
    162 //-----------------------------------------------
    163 
    164 static const struct lfpfracdata fdata[] = {
    165 	{	  0, 0x00000000 }, {   2218896, 0x00916ae6 },
    166 	{  16408100, 0x0433523d }, { 125000000, 0x20000000 },
    167 	{ 250000000, 0x40000000 }, { 287455871, 0x4996b53d },
    168 	{ 375000000, 0x60000000 }, { 500000000, 0x80000000 },
    169 	{ 518978897, 0x84dbcd0e }, { 563730222, 0x90509fb3 },
    170 	{ 563788007, 0x9054692c }, { 583289882, 0x95527c57 },
    171 	{ 607074509, 0x9b693c2a }, { 625000000, 0xa0000000 },
    172 	{ 645184059, 0xa52ac851 }, { 676497788, 0xad2ef583 },
    173 	{ 678910895, 0xadcd1abb }, { 679569625, 0xadf84663 },
    174 	{ 690926741, 0xb0e0932d }, { 705656483, 0xb4a5e73d },
    175 	{ 723553854, 0xb93ad34c }, { 750000000, 0xc0000000 },
    176 	{ 763550253, 0xc3780785 }, { 775284917, 0xc6791284 },
    177 	{ 826190764, 0xd3813ce8 }, { 875000000, 0xe0000000 },
    178 	{ 956805507, 0xf4f134a9 }, { 982570733, 0xfb89c16c }
    179 	};
    180 
    181 
    182 u_int32
    183 my_tick_to_tsf(u_int32 ticks)
    184 {
    185 	// convert nanoseconds to l_fp fractional units, using double
    186 	// precision float calculations or, if available, 64bit integer
    187 	// arithmetic. This should give the precise fraction, rounded to
    188 	// the nearest representation.
    189 
    190 #ifdef HAVE_U_INT64
    191 	return (u_int32)((( ((u_int64)(ticks)) << 32) + 500000000) / 1000000000);
    192 #else
    193 	return (u_int32)((double(ticks)) * 4.294967296 + 0.5);
    194 #endif
    195 	// And before you ask: if ticks >= 1000000000, the result is
    196 	// truncated nonsense, so don't use it out-of-bounds.
    197 }
    198 
    199 
    200 u_int32
    201 my_tsf_to_tick(u_int32 tsf)
    202 {
    203 
    204 	// Inverse operation: converts fraction to microseconds.
    205 #ifdef HAVE_U_INT64
    206 	return (u_int32)(( ((u_int64)(tsf)) * 1000000000 + 0x80000000) >> 32);
    207 #else
    208 	return (u_int32)(double(tsf) / 4.294967296 + 0.5);
    209 #endif
    210 	// Beware: The result might be 10^9 due to rounding!
    211 }
    212 
    213 
    214 
    215 // ---------------------------------------------------------------------
    216 // test support stuff -- part 1
    217 // ---------------------------------------------------------------------
    218 
    219 void
    220 test_Helpers1(void)
    221 {
    222 	struct timespec x;
    223 
    224 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++) {
    225 		x.tv_nsec = -1;
    226 		TEST_ASSERT_FALSE(timespec_isValid(x));
    227 		x.tv_nsec = 0;
    228 		TEST_ASSERT_TRUE(timespec_isValid(x));
    229 		x.tv_nsec = 999999999;
    230 		TEST_ASSERT_TRUE(timespec_isValid(x));
    231 		x.tv_nsec = 1000000000;
    232 		TEST_ASSERT_FALSE(timespec_isValid(x));
    233 	}
    234 
    235 	return;
    236 }
    237 
    238 
    239 //----------------------------------------------------------------------
    240 // test normalisation
    241 //----------------------------------------------------------------------
    242 
    243 void
    244 test_Normalise(void)
    245 {
    246 	long ns;
    247 
    248 	for ( ns = -2000000000; ns <= 2000000000; ns += 10000000) {
    249 		struct timespec x = timespec_init(0, ns);
    250 
    251 		x = normalize_tspec(x);
    252 		TEST_ASSERT_TRUE(timespec_isValid(x));
    253 	}
    254 
    255 	return;
    256 }
    257 
    258 //----------------------------------------------------------------------
    259 // test classification
    260 //----------------------------------------------------------------------
    261 
    262 void
    263 test_SignNoFrac(void)
    264 {
    265 	// sign test, no fraction
    266 	int i;
    267 
    268 	for (i = -4; i <= 4; ++i) {
    269 		struct timespec a = timespec_init(i, 0);
    270 		int E = (i > 0) - (i < 0);
    271 		int r = test_tspec(a);
    272 
    273 		TEST_ASSERT_EQUAL(E, r);
    274 	}
    275 
    276 	return;
    277 }
    278 
    279 
    280 void
    281 test_SignWithFrac(void)
    282 {
    283 	// sign test, with fraction
    284 	int i;
    285 
    286 	for (i = -4; i <= 4; ++i) {
    287 		struct timespec a = timespec_init(i, 10);
    288 		int E = (i >= 0) - (i < 0);
    289 		int r = test_tspec(a);
    290 
    291 		TEST_ASSERT_EQUAL(E, r);
    292 	}
    293 
    294 	return;
    295 }
    296 
    297 //----------------------------------------------------------------------
    298 // test compare
    299 //----------------------------------------------------------------------
    300 void
    301 test_CmpFracEQ(void)
    302 {
    303 	// fractions are equal
    304 	int i, j;
    305 	for (i = -4; i <= 4; ++i)
    306 		for (j = -4; j <= 4; ++j) {
    307 			struct timespec a = timespec_init( i , 200);
    308 			struct timespec b = timespec_init( j , 200);
    309 			int   E = (i > j) - (i < j);
    310 			int   r = cmp_tspec_denorm(a, b);
    311 
    312 			TEST_ASSERT_EQUAL(E, r);
    313 		}
    314 
    315 	return;
    316 }
    317 
    318 
    319 void
    320 test_CmpFracGT(void)
    321 {
    322 	// fraction a bigger fraction b
    323 	int i, j;
    324 
    325 	for (i = -4; i <= 4; ++i)
    326 		for (j = -4; j <= 4; ++j) {
    327 			struct timespec a = timespec_init(i, 999999800);
    328 			struct timespec b = timespec_init(j, 200);
    329 			int   E = (i >= j) - (i < j);
    330 			int   r = cmp_tspec_denorm(a, b);
    331 
    332 			TEST_ASSERT_EQUAL(E, r);
    333 		}
    334 
    335 	return;
    336 }
    337 
    338 
    339 void
    340 test_CmpFracLT(void)
    341 {
    342 	// fraction a less fraction b
    343 	int i, j;
    344 
    345 	for (i = -4; i <= 4; ++i)
    346 		for (j = -4; j <= 4; ++j) {
    347 			struct timespec a = timespec_init(i, 200);
    348 			struct timespec b = timespec_init(j, 999999800);
    349 			int   E = (i > j) - (i <= j);
    350 			int   r = cmp_tspec_denorm(a, b);
    351 
    352 			TEST_ASSERT_EQUAL(E, r);
    353 		}
    354 
    355 	return;
    356 }
    357 
    358 //----------------------------------------------------------------------
    359 // Test addition (sum)
    360 //----------------------------------------------------------------------
    361 
    362 void
    363 test_AddFullNorm(void)
    364 {
    365 	int i, j;
    366 
    367 	for (i = -4; i <= 4; ++i)
    368 		for (j = -4; j <= 4; ++j) {
    369 			struct timespec a = timespec_init(i, 200);
    370 			struct timespec b = timespec_init(j, 400);
    371 			struct timespec E = timespec_init(i + j, 200 + 400);
    372 			struct timespec c;
    373 
    374 			c = add_tspec(a, b);
    375 			TEST_ASSERT_EQUAL_timespec(E, c);
    376 		}
    377 
    378 	return;
    379 }
    380 
    381 
    382 void
    383 test_AddFullOflow1(void)
    384 {
    385 	int i, j;
    386 
    387 	for (i = -4; i <= 4; ++i)
    388 		for (j = -4; j <= 4; ++j) {
    389 			struct timespec a = timespec_init(i, 200);
    390 			struct timespec b = timespec_init(j, 999999900);
    391 			struct timespec E = timespec_init(i + j + 1, 100);
    392 			struct timespec c;
    393 
    394 			c = add_tspec(a, b);
    395 			TEST_ASSERT_EQUAL_timespec(E, c);
    396 		}
    397 
    398 	return;
    399 }
    400 
    401 
    402 void
    403 test_AddNsecNorm(void) {
    404 	int i;
    405 
    406 	for (i = -4; i <= 4; ++i) {
    407 		struct timespec a = timespec_init(i, 200);
    408 		struct timespec E = timespec_init(i, 600);
    409 		struct timespec c;
    410 
    411 		c = add_tspec_ns(a, 600 - 200);
    412 		TEST_ASSERT_EQUAL_timespec(E, c);
    413 	}
    414 
    415 	return;
    416 }
    417 
    418 
    419 void
    420 test_AddNsecOflow1(void)
    421 {
    422 	int i;
    423 
    424 	for (i = -4; i <= 4; ++i) {
    425 		struct timespec a = timespec_init(i, 200);
    426 		struct timespec E = timespec_init(i + 1, 100);
    427 		struct timespec c;
    428 
    429 		c = add_tspec_ns(a, NANOSECONDS - 100);
    430 		TEST_ASSERT_EQUAL_timespec(E, c);
    431 	}
    432 
    433 	return;
    434 }
    435 
    436 //----------------------------------------------------------------------
    437 // test subtraction (difference)
    438 //----------------------------------------------------------------------
    439 
    440 void
    441 test_SubFullNorm(void)
    442 {
    443 	int i, j;
    444 
    445 	for (i = -4; i <= 4; ++i)
    446 		for (j = -4; j <= 4; ++j) {
    447 			struct timespec a = timespec_init( i , 600);
    448 			struct timespec b = timespec_init( j , 400);
    449 			struct timespec E = timespec_init(i-j, 200);
    450 			struct timespec c;
    451 
    452 			c = sub_tspec(a, b);
    453 			TEST_ASSERT_EQUAL_timespec(E, c);
    454 		}
    455 
    456 	return;
    457 }
    458 
    459 
    460 void
    461 test_SubFullOflow(void)
    462 {
    463 	int i, j;
    464 
    465 	for (i = -4; i <= 4; ++i)
    466 		for (j = -4; j <= 4; ++j) {
    467 			struct timespec a = timespec_init(i, 100);
    468 			struct timespec b = timespec_init(j, 999999900);
    469 			struct timespec E = timespec_init(i - j - 1, 200);
    470 			struct timespec c;
    471 
    472 			c = sub_tspec(a, b);
    473 			TEST_ASSERT_EQUAL_timespec(E, c);
    474 		}
    475 
    476 	return;
    477 }
    478 
    479 
    480 void
    481 test_SubNsecNorm(void)
    482 {
    483 	int i;
    484 
    485 	for (i = -4; i <= 4; ++i) {
    486 		struct timespec a = timespec_init(i, 600);
    487 		struct timespec E = timespec_init(i, 200);
    488 		struct timespec c;
    489 
    490 		c = sub_tspec_ns(a, 600 - 200);
    491 		TEST_ASSERT_EQUAL_timespec(E, c);
    492 	}
    493 
    494 	return;
    495 }
    496 
    497 
    498 void
    499 test_SubNsecOflow(void)
    500 {
    501 	int i;
    502 
    503 	for (i = -4; i <= 4; ++i) {
    504 		struct timespec a = timespec_init( i , 100);
    505 		struct timespec E = timespec_init(i-1, 200);
    506 		struct timespec c;
    507 
    508 		c = sub_tspec_ns(a, NANOSECONDS - 100);
    509 		TEST_ASSERT_EQUAL_timespec(E, c);
    510 	}
    511 
    512 	return;
    513 }
    514 
    515 //----------------------------------------------------------------------
    516 // test negation
    517 //----------------------------------------------------------------------
    518 
    519 
    520 void
    521 test_Neg(void)
    522 {
    523 	int i;
    524 
    525 	for (i = -4; i <= 4; ++i) {
    526 		struct timespec a = timespec_init(i, 100);
    527 		struct timespec b;
    528 		struct timespec c;
    529 
    530 		b = neg_tspec(a);
    531 		c = add_tspec(a, b);
    532 		TEST_ASSERT_EQUAL(0, test_tspec(c));
    533 	}
    534 
    535 	return;
    536 }
    537 
    538 //----------------------------------------------------------------------
    539 // test abs value
    540 //----------------------------------------------------------------------
    541 
    542 void
    543 test_AbsNoFrac(void)
    544 {
    545 	int i;
    546 
    547 	for (i = -4; i <= 4; ++i) {
    548 		struct timespec a = timespec_init(i , 0);
    549 		struct timespec b;
    550 
    551 		b = abs_tspec(a);
    552 		TEST_ASSERT_EQUAL((i != 0), test_tspec(b));
    553 	}
    554 
    555 	return;
    556 }
    557 
    558 
    559 void
    560 test_AbsWithFrac(void)
    561 {
    562 	int i;
    563 
    564 	for (i = -4; i <= 4; ++i) {
    565 		struct timespec a = timespec_init(i, 100);
    566 		struct timespec b;
    567 
    568 		b = abs_tspec(a);
    569 		TEST_ASSERT_EQUAL(1, test_tspec(b));
    570 	}
    571 
    572 	return;
    573 }
    574 
    575 // ---------------------------------------------------------------------
    576 // test support stuff -- part 2
    577 // ---------------------------------------------------------------------
    578 
    579 void
    580 test_Helpers2(void)
    581 {
    582 	struct timespec limit = timespec_init(0, 2);
    583 	struct timespec x, y;
    584 	long i;
    585 
    586 	for (x.tv_sec = -2; x.tv_sec < 3; x.tv_sec++)
    587 		for (x.tv_nsec = 1;
    588 		     x.tv_nsec < 1000000000;
    589 		     x.tv_nsec += 499999999) {
    590 			for (i = -4; i < 5; ++i) {
    591 				y = x;
    592 				y.tv_nsec += i;
    593 				if (i >= -2 && i <= 2) {
    594 					TEST_ASSERT_TRUE(AssertTimespecClose(x, y, limit));
    595 				}
    596 				else
    597 				{
    598 					TEST_ASSERT_FALSE(AssertTimespecClose(x, y, limit));
    599 				}
    600 			}
    601 		}
    602 
    603 	return;
    604 }
    605 
    606 //----------------------------------------------------------------------
    607 // conversion to l_fp
    608 //----------------------------------------------------------------------
    609 
    610 void
    611 test_ToLFPbittest(void)
    612 {
    613 	l_fp lfpClose =  l_fp_init(0, 1);
    614 	u_int32 i;
    615 
    616 	for (i = 0; i < 1000000000; i+=1000) {
    617 		struct timespec a = timespec_init(1, i);
    618 		l_fp E= l_fp_init(1, my_tick_to_tsf(i));
    619 		l_fp r;
    620 
    621 		r = tspec_intv_to_lfp(a);
    622 		TEST_ASSERT_TRUE(AssertFpClose(E, r, lfpClose));
    623 	}
    624 
    625 	return;
    626 }
    627 
    628 
    629 void
    630 test_ToLFPrelPos(void)
    631 {
    632 	int i;
    633 
    634 	for (i = 0; i < COUNTOF(fdata); ++i) {
    635 		struct timespec a = timespec_init(1, fdata[i].nsec);
    636 		l_fp E = l_fp_init(1, fdata[i].frac);
    637 		l_fp r;
    638 
    639 		r = tspec_intv_to_lfp(a);
    640 		TEST_ASSERT_EQUAL_l_fp(E, r);
    641 	}
    642 
    643 	return;
    644 }
    645 
    646 
    647 void
    648 test_ToLFPrelNeg(void)
    649 {
    650 	int i;
    651 
    652 	for (i = 0; i < COUNTOF(fdata); ++i) {
    653 		struct timespec a = timespec_init(-1, fdata[i].nsec);
    654 		l_fp E = l_fp_init(~0, fdata[i].frac);
    655 		l_fp r;
    656 
    657 		r = tspec_intv_to_lfp(a);
    658 		TEST_ASSERT_EQUAL_l_fp(E, r);
    659 	}
    660 
    661 	return;
    662 }
    663 
    664 
    665 void
    666 test_ToLFPabs(void)
    667 {
    668 	int i;
    669 
    670 	for (i = 0; i < COUNTOF(fdata); ++i) {
    671 		struct timespec a = timespec_init(1, fdata[i].nsec);
    672 		l_fp E = l_fp_init(1 + JAN_1970, fdata[i].frac);
    673 		l_fp r;
    674 
    675 		r = tspec_stamp_to_lfp(a);
    676 		TEST_ASSERT_EQUAL_l_fp(E, r);
    677 	}
    678 
    679 	return;
    680 }
    681 
    682 //----------------------------------------------------------------------
    683 // conversion from l_fp
    684 //----------------------------------------------------------------------
    685 
    686 void
    687 test_FromLFPbittest(void)
    688 {
    689 	struct timespec limit = timespec_init(0, 2);
    690 
    691 	// Not *exactly* a bittest, because 2**32 tests would take a
    692 	// really long time even on very fast machines! So we do test
    693 	// every 1000 fractional units.
    694 	u_int32 tsf;
    695 	for (tsf = 0; tsf < ~((u_int32)(1000)); tsf += 1000) {
    696 		struct timespec E = timespec_init(1, my_tsf_to_tick(tsf));
    697 		l_fp a = l_fp_init(1, tsf);
    698 		struct timespec r;
    699 
    700 		r = lfp_intv_to_tspec(a);
    701 		// The conversion might be off by one nanosecond when
    702 		// comparing to calculated value.
    703 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    704 	}
    705 
    706 	return;
    707 }
    708 
    709 
    710 void
    711 test_FromLFPrelPos(void)
    712 {
    713 	struct timespec limit = timespec_init(0, 2);
    714 	int i;
    715 
    716 	for (i = 0; i < COUNTOF(fdata); ++i) {
    717 		l_fp a = l_fp_init(1, fdata[i].frac);
    718 		struct timespec E = timespec_init(1, fdata[i].nsec);
    719 		struct timespec r;
    720 
    721 		r = lfp_intv_to_tspec(a);
    722 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    723 	}
    724 
    725 	return;
    726 }
    727 
    728 
    729 void
    730 test_FromLFPrelNeg(void)
    731 {
    732 	struct timespec limit = timespec_init(0, 2);
    733 	int i;
    734 
    735 	for (i = 0; i < COUNTOF(fdata); ++i) {
    736 		l_fp a = l_fp_init(~0, fdata[i].frac);
    737 		struct timespec E = timespec_init(-1, fdata[i].nsec);
    738 		struct timespec r;
    739 
    740 		r = lfp_intv_to_tspec(a);
    741 		TEST_ASSERT_TRUE(AssertTimespecClose(E, r, limit));
    742 	}
    743 
    744 	return;
    745 }
    746 
    747 
    748 // nsec -> frac -> nsec roundtrip, using a prime start and increment
    749 void
    750 test_LFProundtrip(void)
    751 {
    752 	int32_t t;
    753 	u_int32 i;
    754 
    755 	for (t = -1; t < 2; ++t)
    756 		for (i = 4999; i < 1000000000; i += 10007) {
    757 			struct timespec E = timespec_init(t, i);
    758 			l_fp a;
    759 			struct timespec r;
    760 
    761 			a = tspec_intv_to_lfp(E);
    762 			r = lfp_intv_to_tspec(a);
    763 			TEST_ASSERT_EQUAL_timespec(E, r);
    764 		}
    765 
    766 	return;
    767 }
    768 
    769 //----------------------------------------------------------------------
    770 // string formatting
    771 //----------------------------------------------------------------------
    772 
    773 void
    774 test_ToString(void)
    775 {
    776 	static const struct {
    777 		time_t		sec;
    778 		long		nsec;
    779 		const char *	repr;
    780 	} data [] = {
    781 		{ 0, 0,	 "0.000000000" },
    782 		{ 2, 0,	 "2.000000000" },
    783 		{-2, 0, "-2.000000000" },
    784 		{ 0, 1,	 "0.000000001" },
    785 		{ 0,-1,	"-0.000000001" },
    786 		{ 1,-1,	 "0.999999999" },
    787 		{-1, 1, "-0.999999999" },
    788 		{-1,-1, "-1.000000001" },
    789 	};
    790 	int i;
    791 
    792 	for (i = 0; i < COUNTOF(data); ++i) {
    793 		struct timespec a = timespec_init(data[i].sec, data[i].nsec);
    794 		const char * E = data[i].repr;
    795 		const char * r = tspectoa(a);
    796 		TEST_ASSERT_EQUAL_STRING(E, r);
    797 	}
    798 
    799 	return;
    800 }
    801 
    802 // -*- EOF -*-
    803