[CSRSS]
[reactos.git] / base / applications / calc / utl.c
1 #include "calc.h"
2
3 void prepare_rpn_result_2(calc_number_t *rpn, TCHAR *buffer, int size, int base)
4 {
5 calc_number_t tmp;
6 int width;
7
8 switch (base) {
9 case IDC_RADIO_HEX:
10 _stprintf(buffer, TEXT("%I64X"), rpn->i);
11 break;
12 case IDC_RADIO_DEC:
13 /*
14 * Modifed from 17 to 16 for fixing this bug:
15 * 14+14+6.3+6.3= 40.5999999 instead of 40.6
16 * So, it's probably better to leave the least
17 * significant digit out of the display.
18 */
19 #define MAX_LD_WIDTH 16
20 /* calculate the width of integer number */
21 width = (rpn->f==0) ? 1 : (int)log10(fabs(rpn->f))+1;
22 if (calc.sci_out == TRUE || width > MAX_LD_WIDTH || width < -MAX_LD_WIDTH)
23 _stprintf(buffer, TEXT("%#e"), rpn->f);
24 else {
25 TCHAR *ptr, *dst;
26
27 ptr = buffer + _stprintf(buffer, TEXT("%#*.*f"), width, ((MAX_LD_WIDTH-width-1)>=0) ? MAX_LD_WIDTH-width-1 : 0, rpn->f);
28 /* format sring ensures there is a '.': */
29 dst = _tcschr(buffer, TEXT('.'));
30 while (--ptr > dst)
31 if (*ptr != TEXT('0'))
32 break;
33
34 /* put the string terminator for removing the final '0' (if any) */
35 ptr[1] = TEXT('\0');
36 /* check if the number finishes with '.' */
37 if (ptr == dst)
38 /* remove the dot (it will be re-added later) */
39 ptr[0] = TEXT('\0');
40 }
41 #undef MAX_LD_WIDTH
42 break;
43 case IDC_RADIO_OCT:
44 _stprintf(buffer, TEXT("%I64o"), rpn->i);
45 break;
46 case IDC_RADIO_BIN:
47 if (rpn->i == 0) {
48 buffer[0] = TEXT('0');
49 buffer[1] = TEXT('\0');
50 break;
51 }
52 tmp = *rpn;
53 buffer[0] = TEXT('\0');
54 while (tmp.u) {
55 memmove(buffer+1, buffer, (size-1)*sizeof(TCHAR));
56 if (tmp.u & 1)
57 calc.buffer[0] = TEXT('1');
58 else
59 calc.buffer[0] = TEXT('0');
60 tmp.u >>= 1;
61 }
62 break;
63 }
64 }
65
66 void convert_text2number_2(calc_number_t *a)
67 {
68 TCHAR *ptr;
69
70 switch (calc.base) {
71 case IDC_RADIO_HEX:
72 _stscanf(calc.buffer, TEXT("%I64X"), &(a->i));
73 break;
74 case IDC_RADIO_DEC:
75 _stscanf(calc.buffer, TEXT("%lf"), &(a->f));
76 break;
77 case IDC_RADIO_OCT:
78 _stscanf(calc.buffer, TEXT("%I64o"), &(a->i));
79 break;
80 case IDC_RADIO_BIN:
81 ptr = calc.buffer;
82 a->i = 0;
83 while (*ptr != TEXT('\0')) {
84 a->i <<= 1;
85 if (*ptr++ == TEXT('1'))
86 a->i |= 1;
87 }
88 break;
89 }
90 }
91
92 void convert_real_integer(unsigned int base)
93 {
94 switch (base) {
95 case IDC_RADIO_DEC:
96 calc.code.f = (double)calc.code.i;
97 break;
98 case IDC_RADIO_OCT:
99 case IDC_RADIO_BIN:
100 case IDC_RADIO_HEX:
101 if (calc.base == IDC_RADIO_DEC) {
102 calc.code.i = (__int64)calc.code.f;
103 apply_int_mask(&calc.code);
104 }
105 break;
106 }
107 }