• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  This Software is provided under the Zope Public License (ZPL) Version 2.1.
3 
4  Copyright (c) 2009 - 2013 by the mingw-w64 project
5 
6  See the AUTHORS file for the list of contributors to the mingw-w64 project.
7 
8  This license has been certified as open source. It has also been designated
9  as GPL compatible by the Free Software Foundation (FSF).
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14    1. Redistributions in source code must retain the accompanying copyright
15       notice, this list of conditions, and the following disclaimer.
16    2. Redistributions in binary form must reproduce the accompanying
17       copyright notice, this list of conditions, and the following disclaimer
18       in the documentation and/or other materials provided with the
19       distribution.
20    3. Names of the copyright holders must not be used to endorse or promote
21       products derived from this software without prior written permission
22       from the copyright holders.
23    4. The right to distribute this software or to use it for any purpose does
24       not give you the right to use Servicemarks (sm) or Trademarks (tm) of
25       the copyright holders.  Use of them is covered by separate agreement
26       with the copyright holders.
27    5. If any files are modified, you must cause the modified files to carry
28       prominent notices stating that you changed the files and the date of
29       any change.
30 
31  Disclaimer
32 
33  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
34  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
36  EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
37  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
39  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
40  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
41  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44 
45 /*
46  * Prelim Encoder/Decoder Test
47  * Build with -std=gnu99 -Wall -Wextra -Wformat -Wstrict-aliasing -Wshadow -Wpacked \
48  * -Winline -Wimplicit-function-declaration -Wmissing-noreturn -Wmissing-prototypes \
49  * -g -O2 -m32 -std=gnu99 -frounding-math -fsignaling-nans -Wno-inline -DCONFIG_32 \
50  * -DPPRO -DASM -Dmpdecimal_header=\"mpdecimal-i686.h\" -fno-strict-aliasing \
51  * -Wno-unused-function
52 */
53 
54 #include <stdio.h>
55 #include <inttypes.h>
56 #include "dfp_internal.h"
57 #include mpdecimal_header
58 
59 static const _Decimal32 dec32 = 0.0DF;
60 static const _Decimal64 dec64 = 0.0DD;
61 static const _Decimal128 dec128 = 0.0DL;
62 
print_mpd(const mpd_t * in)63 static void print_mpd(const mpd_t *in){
64   printf("----\n");
65   printf("flags: %d\n",in->flags);
66   printf("exp: %I64d\n",(uint64_t)in->exp);
67   printf("digits: %I64d\n",(uint64_t)in->digits);
68   printf("trail: %I64d\n",(uint64_t)mpd_trail_zeros(in));
69   printf("len: %I64d\n",(uint64_t)in->len);
70   printf("alloc: %I64d\n",(uint64_t)in->alloc);
71   printf("data: ");
72   for(mpd_ssize_t i = 0; i < in->len; i++){
73     printf("[%09I64x]",(uint64_t)in->data[i]);
74   }
75   printf("\n");
76   printf("----\n");
77 }
78 
print_dec32(const _Decimal32 * in)79 static void print_dec32(const _Decimal32 *in){
80   ud32 ret;
81   ret.d = *in;
82   printf("----\n");
83   printf("sign %x\n", ret.t0.sign);
84   printf("bits %x\n", ret.t0.bits);
85   printf("flag %x\n", ret.t0.flag);
86   if(ret.t0.bits == 0x3){
87     printf("exp %d\n", ret.t2.exponent);
88     printf("mantissa %d\n", ret.t2.mantissa);
89   } else {
90     printf("exp %d\n", ret.t1.exponent);
91     printf("mantissa %d\n", ret.t1.mantissa);
92   }
93   printf("----\n");
94 }
95 
print_dec64(const _Decimal64 * in)96 static void print_dec64(const _Decimal64 *in){
97   ud64 ret;
98   ret.d = *in;
99   printf("----\n");
100   printf("sign %x\n", ret.t0.sign);
101   printf("bits %x\n", ret.t0.bits);
102   printf("flag %x\n", ret.t0.flag);
103   if(ret.t0.bits == 0x3){
104     printf("exp %d\n", ret.t2.exponent);
105     printf("mantissa %I64u\n", (uint64_t)ret.t2.mantissa);
106   } else {
107     printf("exp %d\n", ret.t1.exponent);
108     printf("mantissa %I64u\n", (uint64_t)ret.t1.mantissa);
109   }
110   printf("----\n");
111 }
112 
print_dec128(const _Decimal128 * in)113 static void print_dec128(const _Decimal128 *in){
114   ud128 ret;
115   ret.d = *in;
116   printf("----\n");
117   printf("sign %x\n", ret.t0.sign);
118   printf("bits %x\n", ret.t0.bits);
119   printf("flag %x\n", ret.t0.flag);
120   if(ret.t0.bits == 0x3){
121     printf("exp %d\n", ret.t2.exponent);
122     printf("mantissaL %I64u\n", (uint64_t)ret.t2.mantissaL);
123     printf("mantissaH %I64u\n", (uint64_t)ret.t2.mantissaH);
124   } else {
125     printf("exp %d\n", ret.t1.exponent);
126     printf("mantissaL %I64u\n", (uint64_t)ret.t1.mantissaL);
127     printf("mantissaH %I64u\n", (uint64_t)ret.t1.mantissaH);
128   }
129   printf("----\n");
130 }
131 
132 
dec_to_mpd_conv(mpd_context_t * ctx,mpd_t * result,const int64_t significand_low,const int64_t exponent_part)133 static void dec_to_mpd_conv(mpd_context_t * ctx, mpd_t *result, const int64_t significand_low, const int64_t exponent_part){
134   uint32_t status = 0;
135   mpd_t *ten, *exp_pow, *exp_partmpd, *significand_partmpd;
136   ten = mpd_qnew();
137   exp_pow = mpd_qnew();
138   exp_partmpd = mpd_qnew();
139   significand_partmpd = mpd_qnew();
140 
141   mpd_qset_i64(ten,10LL,ctx,&status);
142   mpd_qset_i64(significand_partmpd,significand_low,ctx,&status);
143   mpd_qset_i64(exp_partmpd,exponent_part,ctx,&status);
144   mpd_qpow(exp_pow,ten,exp_partmpd,ctx,&status);
145   mpd_qmul(result,significand_partmpd,exp_pow,ctx,&status);
146 
147   mpd_del(ten);
148   mpd_del(exp_pow);
149   mpd_del(exp_partmpd);
150   mpd_del(significand_partmpd);
151 }
152 
dec128_to_mpd_conv(mpd_context_t * ctx,mpd_t * result,const uint64_t significand_low,const int64_t significand_high,const int64_t exponent_part)153 static void dec128_to_mpd_conv(mpd_context_t * ctx, mpd_t *result, const uint64_t significand_low, const int64_t significand_high, const int64_t exponent_part){
154   uint32_t status = 0;
155   mpd_t *ten, *sig1, *sig2, *stemp, *sig, *s64, *exp_pow, *exp_partmpd;
156   ten = mpd_qnew();
157   s64 = mpd_qnew();
158   sig1 = mpd_qnew();
159   sig2 = mpd_qnew();
160   stemp = mpd_qnew();
161   sig = mpd_qnew();
162   exp_pow = mpd_qnew();
163   exp_partmpd = mpd_qnew();
164   mpd_qset_i64(ten,10LL,ctx,&status);
165   /* 2^64 */
166   mpd_qset_string(s64,"18446744073709551616",ctx,&status);
167   mpd_qset_u64(sig1,significand_low,ctx,&status);
168   mpd_qset_i64(sig2,significand_high,ctx,&status);
169   mpd_qmul(stemp,sig2,s64,ctx,&status);
170   mpd_qadd(sig,stemp,sig1,ctx,&status);
171   mpd_qset_i64(exp_partmpd,exponent_part,ctx,&status);
172   mpd_qpow(exp_pow,ten,exp_partmpd,ctx,&status);
173   mpd_qmul(result,sig,exp_pow,ctx,&status);
174   mpd_del(ten);
175   mpd_del(sig1);
176   mpd_del(sig2);
177   mpd_del(sig);
178   mpd_del(stemp);
179   mpd_del(s64);
180   mpd_del(exp_pow);
181   mpd_del(exp_partmpd);
182 }
183 
dec128_to_mpd(mpd_context_t * ctx,mpd_t * result,const _Decimal128 deci)184 static uint32_t dec128_to_mpd(mpd_context_t * ctx, mpd_t *result, const _Decimal128 deci){
185   int64_t significand2, exp_part;
186   uint64_t significand1;
187   ud128 in = {.d = deci};
188 
189   if(in.t0.bits == 0x3){ /*case 11 */
190     /* should not enter here */
191     exp_part = in.t2.exponent;
192     significand1 = in.t2.mantissaL;
193     significand2 = (in.t2.mantissaH | (0x1ULL << 49)) * ((in.t2.sign) ? -1 : 1);
194   } else {
195     exp_part = in.t1.exponent;
196     significand1 = in.t1.mantissaL;
197     significand2 = in.t1.mantissaH  * ((in.t1.sign) ? -1 : 1);
198   }
199 
200   printf("%I64d %I64d\n", significand1, significand2);
201 
202   exp_part -= 6176; /* exp bias */
203   dec128_to_mpd_conv(ctx, result, significand1, significand2, exp_part);
204   return 0;
205 }
206 
dec64_to_mpd(mpd_context_t * ctx,mpd_t * result,const _Decimal64 deci)207 static uint32_t dec64_to_mpd(mpd_context_t * ctx, mpd_t *result, const _Decimal64 deci){
208   int64_t significand, exp_part;
209   ud64 in = {.d = deci};
210 
211   if(in.t0.bits == 0x3){ /*case 11 */
212     exp_part = in.t2.exponent;
213     significand = (in.t2.mantissa | (0x1ULL << 53)) * ((in.t2.sign) ? -1 : 1);
214   } else {
215     exp_part = in.t1.exponent;
216     significand = in.t1.mantissa  * ((in.t1.sign) ? -1 : 1);
217   }
218   exp_part -= 398; /* exp bias */
219   dec_to_mpd_conv(ctx, result, significand, exp_part);
220   return 0;
221 }
222 
dec32_to_mpd(mpd_context_t * ctx,mpd_t * result,const _Decimal32 deci)223 static uint32_t dec32_to_mpd(mpd_context_t * ctx, mpd_t *result, const _Decimal32 deci){
224   int64_t significand, exp_part;
225   ud32 in = {.d = deci};
226 
227   if(in.t0.bits == 0x3){ /*case 11 */
228     exp_part = in.t2.exponent;
229     significand = (in.t2.mantissa | (0x1ULL << 23)) * ((in.t2.sign) ? -1 : 1);
230   } else {
231     exp_part = in.t1.exponent;
232     significand = in.t1.mantissa  * ((in.t1.sign) ? -1 : 1);
233   }
234   exp_part -= 101; /* exp bias */
235   dec_to_mpd_conv(ctx, result, significand, exp_part);
236   return 0;
237 }
238 
mpd_to_dec32(mpd_t * in)239 static _Decimal32 mpd_to_dec32(mpd_t *in){
240   uint32_t exp_part, significand;
241   uint32_t status = 0;
242   ud32 ret;
243   mpd_context_t ctx;
244   uint16_t *bases_data;
245   size_t bases;
246 
247   mpd_ieee_context(&ctx,MPD_DECIMAL32);
248   mpd_qfinalize(in, &ctx,&status);
249 
250   exp_part = in->exp + (uint32_t)mpd_trail_zeros(in) + 101LL; /* rough guess? */
251   in->exp = 0;
252   bases = mpd_sizeinbase(in, UINT16_MAX+1);
253   bases_data = __mingw_dfp_get_globals()->mpd_callocfunc(bases < 2 ? 2 : bases,sizeof(uint16_t));
254   mpd_qexport_u16(bases_data,bases,UINT16_MAX+1,in,&status);
255   significand = bases_data[0] | (uint32_t)bases_data[1] << 16 ;
256   __mingw_dfp_get_globals()->mpd_free(bases_data);
257   ret.t0.sign = mpd_isnegative(in);
258   if((significand & (0x7ULL << 21)) == (0x1ULL << 23)) { /* 100 MSB? */
259     ret.t2.bits = 0x3;
260     ret.t2.mantissa = significand;
261     ret.t2.exponent = exp_part;
262   } else {
263     ret.t1.mantissa = significand;
264     ret.t1.exponent = exp_part;
265   }
266   return ret.d;
267 }
268 
mpd_to_dec64(mpd_t * in)269 static _Decimal64 mpd_to_dec64(mpd_t *in){
270   uint64_t exp_part, significand;
271   uint32_t status = 0;
272   size_t bases;
273   uint16_t *bases_data;
274   ud64 ret;
275   mpd_context_t ctx;
276 
277   mpd_ieee_context(&ctx,MPD_DECIMAL64);
278   mpd_qfinalize(in, &ctx,&status);
279 
280   exp_part = in->exp + (uint64_t)mpd_trail_zeros(in) + 398LL; /* rough guess? */
281   in->exp = 0;
282   bases = mpd_sizeinbase(in, UINT16_MAX+1);
283   bases_data = __mingw_dfp_get_globals()->mpd_callocfunc(bases < 4 ? 4 : bases,sizeof(uint16_t));
284   mpd_qexport_u16(bases_data,bases,UINT16_MAX+1,in,&status);
285   significand = bases_data[0] | (uint64_t)bases_data[1] << 16 | (uint64_t)bases_data[2] << 32 | (uint64_t)bases_data[3] << 48;
286   __mingw_dfp_get_globals()->mpd_free(bases_data);
287   ret.t0.sign = mpd_isnegative(in);
288   if((significand & (0x7ULL << 51)) == (0x1ULL << 53)) { /* 100 MSB? */
289     ret.t2.bits = 0x3;
290     ret.t2.mantissa = significand;
291     ret.t2.exponent = exp_part;
292   } else {
293     ret.t1.mantissa = significand;
294     ret.t1.exponent = exp_part;
295   }
296   return ret.d;
297 }
298 
mpd_to_dec128(mpd_t * in)299 static _Decimal128 mpd_to_dec128(mpd_t *in){
300   uint64_t exp_part,significand[2];
301   uint16_t *bases_data;
302   ud128 ret;
303   mpd_context_t ctx;
304   size_t bases;
305   uint32_t status = 0;
306 
307   mpd_ieee_context(&ctx,MPD_DECIMAL128);
308   mpd_qfinalize(in, &ctx,&status);
309   exp_part = in->exp + (uint64_t)mpd_trail_zeros(in) + 6176LL; /* rough guess? */
310   in->exp = 0;
311   bases = mpd_sizeinbase(in, UINT16_MAX+1);
312   bases_data = __mingw_dfp_get_globals()->mpd_callocfunc(bases < 8 ? 8 : bases,sizeof(uint16_t));
313   mpd_qexport_u16(bases_data,bases,UINT16_MAX+1,in,&status);
314   significand[0] = bases_data[0] | (uint64_t)bases_data[1] << 16 | (uint64_t)bases_data[2] << 32 | (uint64_t)bases_data[3] << 48;
315   significand[1] = bases_data[4] | (uint64_t)bases_data[5] << 16 | (uint64_t)bases_data[6] << 32 | (uint64_t)bases_data[7] << 48;
316   __mingw_dfp_get_globals()->mpd_free(bases_data);
317   ret.t0.sign = mpd_isnegative(in);
318   if((significand[1] & (0x7ULL << 57)) == (0x1ULL << 49)) { /* 100 MSB? */
319     ret.t2.bits = 0x3;
320     ret.t2.mantissaL = significand[0];
321     ret.t2.mantissaH = significand[1];
322     ret.t2.exponent = exp_part;
323   } else {
324     ret.t1.mantissaL = significand[0];
325     ret.t1.mantissaH = significand[1];
326     ret.t1.exponent = exp_part;
327   }
328   return ret.d;
329 
330 }
331 
main()332 int main(){
333   mpd_context_t ctx;
334   mpd_t *result1;
335   mpd_t *result2;
336   mpd_t *result3;
337   mpd_setminalloc(MPD_MINALLOC_MAX);
338   mpd_ieee_context(&ctx, 160);
339   result1 = mpd_qnew();
340   result2 = mpd_qnew();
341   result3 = mpd_qnew();
342   //mpd_qset_u64(result1,2ULL,&ctx,&status);
343   dec32_to_mpd(&ctx,result1,dec32);
344   dec64_to_mpd(&ctx,result2,dec64);
345   dec128_to_mpd(&ctx,result3,dec128);
346   //mpd_qset_u64(result2,4ULL,&ctx,&status);
347   //mpd_qpow(result3,result1,result2,&ctx,&status);
348   mpd_print(result1);
349   mpd_print(result2);
350   mpd_print(result3);
351 
352   /*print_mpd(result1);
353   print_mpd(result2);
354   print_mpd(result3);*/
355 
356   _Decimal32 ddd = mpd_to_dec32(result1);
357   printf ("Compare is %d\n", memcmp(&ddd,&dec32,sizeof(_Decimal32)));
358   printf ("0x%x\n0x%x\n", *((uint32_t *)(void *)&ddd), *((uint32_t *)(void *)&dec32));
359 
360   _Decimal64 ddd64 = mpd_to_dec64(result2);
361   printf ("Compare is %d\n", memcmp(&ddd64,&dec64,sizeof(_Decimal64)));
362   printf ("0x%I64x\n0x%I64x\n", *((uint64_t *)(void *)&ddd64), *((uint64_t *)(void *)&dec64));
363 
364   _Decimal128 ddd128 = mpd_to_dec128(result3);
365   printf ("Compare is %d\n", memcmp(&ddd128,&dec128,sizeof(_Decimal128)));
366   printf ("0x%I64d\n0x%I64x\n", *((uint64_t *)(void *)&ddd128), *((uint64_t *)(void *)&dec128));
367 
368   mpd_del(result1);
369   mpd_del(result2);
370   mpd_del(result3);
371 
372   print_dec32(&dec32);
373   print_dec64(&dec64);
374   print_dec128(&dec128);
375   return 0;
376 }
377