aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar gingerBill 2016-07-30 00:10:28 +0100
committerGravatar gingerBill 2016-07-30 00:10:28 +0100
commit4e7b07c9a794c31e2587175314d560accbf625ab (patch)
tree0750690338f24489c1f70493d3ad5e8b59b93fe8
parentMinor fixes (diff)
gb_str_to_f* fix
-rw-r--r--gb.h144
1 files changed, 63 insertions, 81 deletions
diff --git a/gb.h b/gb.h
index eb802ea..af63b68 100644
--- a/gb.h
+++ b/gb.h
@@ -1,4 +1,4 @@
-/* gb.h - v0.26b - Ginger Bill's C Helper Library - public domain
+/* gb.h - v0.26c - Ginger Bill's C Helper Library - public domain
- no warranty implied; use at your own risk
This is a single header file with a bunch of useful stuff
@@ -58,6 +58,7 @@ TODOS
- More date & time functions
VERSION HISTORY
+ 0.26c - gb_str_to_f* fix
0.26b - Minor fixes
0.26a - gbString Fix
0.26 - Default allocator flags and generic hash table
@@ -635,7 +636,7 @@ extern "C++" {
#define GB_DEFER_1(x, y) x##y
#define GB_DEFER_2(x, y) GB_DEFER_1(x, y)
#define GB_DEFER_3(x) GB_DEFER_2(x, __COUNTER__)
- #define defer(code) auto GB_DEFER_3(_defer_) = gb__defer_func([&](){code;})
+ #define defer(code) auto GB_DEFER_3(_defer_) = gb__defer_func([&]()->void{code;})
}
// Example
@@ -1631,7 +1632,8 @@ GB_STATIC_ASSERT(GB_ARRAY_GROW_FORMULA(0) > 0);
void **gb__array_ = cast(void **)&(x); \
gbArrayHeader *gb__ah = cast(gbArrayHeader *)gb_alloc(allocator_, gb_size_of(gbArrayHeader)+gb_size_of(*(x))*(cap)); \
gb__ah->allocator = allocator_; \
- gb__ah->count = gb__ah->capacity = 0; \
+ gb__ah->count = 0; \
+ gb__ah->capacity = cap; \
*gb__array_ = cast(void *)(gb__ah+1); \
} while (0)
@@ -6222,91 +6224,66 @@ gb_inline void gb_u64_to_str(u64 value, char *string, i32 base) {
}
gb_inline f32 gb_str_to_f32(char const *str, char **end_ptr) {
- f32 result = 0.0f;
- isize signed_exponent = 0;
- char c;
- for (c = *str; c != '\0' && gb_char_is_digit(c); c = *str++)
- result = result*10.0f + (c-'0');
-
- if (c == '.') {
- for (c = *str++; c != '\0' && gb_char_is_digit(c); c = *str++) {
- result = result*1.0f + (c-'0');
- signed_exponent--;
- }
- }
-
- if (c == 'e' || c == 'E') {
- i64 sign = +1, i = 0;
- c = *str++;
- if (c == '+') {
- c = *str++;
- } else if (c == '-') {
- c = *str++;
- sign = -1;
- }
- while (gb_char_is_digit(c)) {
- i = i*10 + (c-'0');
- c = *str++;
- }
- signed_exponent += i*sign;
- }
-
- while (signed_exponent > 0) {
- result *= 10.0f;
- signed_exponent--;
- }
- while (signed_exponent < 0) {
- result *= 0.1f;
- signed_exponent++;
- }
-
- if (end_ptr) *end_ptr = cast(char *)str;
-
- return result;
+ f64 f = gb_str_to_f64(str, end_ptr);
+ f32 r = cast(f32)f;
+ return r;
}
+gb_inline f64 gb_str_to_f64(char const *str, char **end_ptr) {
+ f64 result, value, sign, scale;
+ i32 frac;
+ while (gb_char_is_space(*str)) {
+ str++;
+ }
-gb_inline f64 gb_str_to_f64(char const *str, char **end_ptr) {
- f64 result = 0.0;
- isize signed_exponent = 0;
- char c;
- for (c = *str; c != '\0' && gb_char_is_digit(c); c = *str++)
- result = result*10.0 + (c-'0');
+ sign = 1.0;
+ if (*str == '-') {
+ sign = -1.0;
+ str++;
+ } else if (*str == '+') {
+ str++;
+ }
+ for (value = 0.0; gb_char_is_digit(*str); str++) {
+ value = value * 10.0 + (*str-'0');
+ }
- if (c == '.') {
- for (c = *str; c != '\0' && gb_char_is_digit(c); c = *str++) {
- result = result*1.0 + (c-'0');
- signed_exponent--;
+ if (*str == '.') {
+ f64 pow10 = 10.0;
+ str++;
+ while (gb_char_is_digit(*str)) {
+ value += (*str-'0') / pow10;
+ pow10 *= 10.0;
+ str++;
}
}
- if (c == 'e' || c == 'E') {
- i64 sign = +1, i = 0;
- c = *str++;
- if (c == '+') {
- c = *str++;
- } else if (c == '-') {
- c = *str++;
- sign = -1;
+ frac = 0;
+ scale = 1.0;
+ if ((*str == 'e') || (*str == 'E')) {
+ u32 exp;
+
+ str++;
+ if (*str == '-') {
+ frac = 1;
+ str++;
+ } else if (*str == '+') {
+ str++;
}
- while (gb_char_is_digit(c)) {
- i = i*10 + (c-'0');
- c = *str++;
+
+ for (exp = 0; gb_char_is_digit(*str); str++) {
+ exp = exp * 10 + (*str-'0');
}
- signed_exponent += i*sign;
- }
+ if (exp > 308) exp = 308;
- while (signed_exponent > 0) {
- result *= 10.0;
- signed_exponent--;
- }
- while (signed_exponent < 0) {
- result *= 0.1;
- signed_exponent++;
+ while (exp >= 50) { scale *= 1e50; exp -= 50; }
+ while (exp >= 8) { scale *= 1e8; exp -= 8; }
+ while (exp > 0) { scale *= 10.0; exp -= 1; }
}
+ result = sign * (frac ? (value / scale) : (value * scale));
+
if (end_ptr) *end_ptr = cast(char *)str;
return result;
@@ -8005,13 +7982,13 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va
if (*fmt == '%') {
do {
- switch (*fmt++) {
- case '-': info.flags |= gbFmt_Minus; fmt++; break;
- case '+': info.flags |= gbFmt_Plus; fmt++; break;
- case '#': info.flags |= gbFmt_Alt; fmt++; break;
- case ' ': info.flags |= gbFmt_Space; fmt++; break;
- case '0': info.flags |= gbFmt_Zero; fmt++; break;
- default: info.flags |= gbFmt_Done; break;
+ switch (*++fmt) {
+ case '-': info.flags |= gbFmt_Minus; break;
+ case '+': info.flags |= gbFmt_Plus; break;
+ case '#': info.flags |= gbFmt_Alt; break;
+ case ' ': info.flags |= gbFmt_Space; break;
+ case '0': info.flags |= gbFmt_Zero; break;
+ default: info.flags |= gbFmt_Done; break;
}
} while (!(info.flags & gbFmt_Done));
}
@@ -8042,6 +8019,7 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va
info.flags &= ~gbFmt_Zero;
}
+
switch (*fmt++) {
case 'h':
if (*fmt == 'h') { // hh => char
@@ -8122,6 +8100,10 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va
info.flags |= (gbFmt_Lower|gbFmt_Unsigned|gbFmt_Alt|gbFmt_Intptr);
break;
+ case '%':
+ len = gb__print_char(text, remaining, &info, '%');
+ break;
+
default: fmt--; break;
}