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