-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstrtonum.cpp
126 lines (102 loc) · 3.01 KB
/
strtonum.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <iostream>
#include <stdlib.h> // malloc()
#include <stdio.h> //puts(), gets(), printf()
#include <string.h> // strlen()
#include <inttypes.h> // fixed width integer types
#include <math.h> // pow()
// the function prototypes
inline int8_t chartonum(const char&); // returns numerical value of single digit
char* firstDecimal(char*); // returns address of first decimal
int32_t strtoint(char const*); // converts a string to an int
double strtodbl(char const*); // converts an string to a double
int main(){
//allocate 25 digits worth of memory for the user's number
char* strNum = (char*) malloc(25);
puts("Give me a number, I'll divide it by 2.\n");
double ans;
gets(strNum);
try {
ans = strtodbl(strNum);
} catch (char const* e) {
puts(e);
}
// http://www.cplusplus.com/reference/cstdio/printf/
printf("(%s / 2) = %f\n", strNum, ans / 2);
}
// converts a digit into a number
inline int8_t chartonum(const char& num){
switch (num) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
default: throw "chartonum(): invalid character given.";
}
}
// converts a string into an int
int32_t strtoint(char const* str){
// skip any preceeding spaces
while (*str == ' ') str++;
// determine if it's positive or negative
signed char sign = 1;
if (*str == '-') {
sign = -1;
str++;
}
// in case there's a space between the number and the decimal
while (*str == ' ') str++;
// get signifigance of the first digit
uint16_t pwr = strlen(str), ret = 0;
// iterate through the digits summing up the value
while (*str)
ret += chartonum(*(str++)) * pow(10, --pwr);
return sign * ret;
}
// finds address of first decimal
char* firstDecimal(char* str){
// increment until reaching a decimal or the end of the string
while (*str != '\0' && *str != '.')
str++;
// return null if there are no decimals
if (*str == '\0')
return (char*) NULL;
return str;
}
// converts a string to a double
double strtodbl(char const* str){
double ret = 0;
const char* cpy = str;
// skip any preceeding spaces
while (*str == ' ') str++;
// mark whether or not it's negative
int8_t sign = 1;
if (*str == '-') {
sign = -1;
str++;
}
// in case there's a space between the number and the decimal
while (*str == ' ') str++;
// find the signifigance of the fist digit
int16_t pwr; // power of the first digit (10^x)
char* dec = firstDecimal((char*)str); // addr. of the first decimal
if (dec == NULL) // no decimals
pwr = strlen(str) - 1;
else pwr = dec - str - 1;
int decimalCount = 0;
// iterate through the characters
while (*str) {
if (*str == '.')// skip decimal
if (str++ != dec) { // > 1 decimals
throw strcat(strcat("strtodbl(\"", cpy), "\") invalid number (too many decimals)");
}
ret += chartonum(*str) * pow(10, pwr--); // assumes base-10 number-system
str++; //next digit
}
return sign * ret;
}