mirror of
https://github.com/QB64-Phoenix-Edition/QB64pe.git
synced 2024-09-20 09:04:43 +00:00
Merge pull request #458 from mkilgore/libqb-refactor
Libqb refactor - Part 5
This commit is contained in:
commit
2693733b37
5 changed files with 303 additions and 281 deletions
|
@ -12776,6 +12776,8 @@ int32 hexoct2uint64(qbs *h) {
|
||||||
hexoct2uint64_value = result;
|
hexoct2uint64_value = result;
|
||||||
return 3;
|
return 3;
|
||||||
} // type == 3
|
} // type == 3
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// input method (complex, calls other qbs functions)
|
// input method (complex, calls other qbs functions)
|
||||||
|
@ -17632,281 +17634,6 @@ wait:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qbs *func__bin(int64 value, int32 neg_bits) {
|
|
||||||
|
|
||||||
static int32 i, i2, i3, neg;
|
|
||||||
static int64 value2;
|
|
||||||
static qbs *str;
|
|
||||||
|
|
||||||
str = qbs_new(64, 1);
|
|
||||||
|
|
||||||
// negative?
|
|
||||||
if ((value >> 63) & 1)
|
|
||||||
neg = 1;
|
|
||||||
else
|
|
||||||
neg = 0;
|
|
||||||
|
|
||||||
// calc. most significant bit
|
|
||||||
i2 = 0;
|
|
||||||
value2 = value;
|
|
||||||
if (neg) {
|
|
||||||
for (i = 1; i <= 64; i++) {
|
|
||||||
if (!(value2 & 1))
|
|
||||||
i2 = i;
|
|
||||||
value2 >>= 1;
|
|
||||||
}
|
|
||||||
if (i2 >= neg_bits) {
|
|
||||||
// doesn't fit in neg_bits, so expand to next 16/32/64 boundary
|
|
||||||
i3 = 64;
|
|
||||||
if (i2 < 32)
|
|
||||||
i3 = 32;
|
|
||||||
if (i2 < 16)
|
|
||||||
i3 = 16;
|
|
||||||
i2 = i3;
|
|
||||||
} else
|
|
||||||
i2 = neg_bits;
|
|
||||||
} else {
|
|
||||||
for (i = 1; i <= 64; i++) {
|
|
||||||
if (value2 & 1)
|
|
||||||
i2 = i;
|
|
||||||
value2 >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i2) {
|
|
||||||
str->chr[0] = 48;
|
|
||||||
str->len = 1;
|
|
||||||
return str;
|
|
||||||
} //"0"
|
|
||||||
|
|
||||||
// calc. number of characters required in i3
|
|
||||||
i3 = i2; // equal for BIN$ because one bit = one char
|
|
||||||
|
|
||||||
// build string
|
|
||||||
str->len = i3;
|
|
||||||
i3--;
|
|
||||||
for (i = 1; i <= i2; i++) {
|
|
||||||
str->chr[i3--] = (value & 1) + 48;
|
|
||||||
value >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: QBASIC doesn't have a BIN$ function
|
|
||||||
// QB64 uses 32 bin digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
|
||||||
// it uses up to 64 bin digits before generating an "OVERFLOW" error
|
|
||||||
// performs overflow check before calling func__bin
|
|
||||||
qbs *func__bin_float(long double value) {
|
|
||||||
static qbs *str;
|
|
||||||
static int64 ivalue;
|
|
||||||
static int64 uivalue;
|
|
||||||
// ref: uint64 0-18446744073709551615
|
|
||||||
// int64 \969223372036854775808 to 9223372036854775807
|
|
||||||
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
|
||||||
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
|
||||||
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
|
||||||
str = qbs_new(0, 1);
|
|
||||||
error(6); // Overflow
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (value >= 0) {
|
|
||||||
uivalue = qbr_longdouble_to_uint64(value);
|
|
||||||
ivalue = uivalue;
|
|
||||||
} else {
|
|
||||||
ivalue = qbr(value);
|
|
||||||
}
|
|
||||||
return func__bin(ivalue, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
qbs *func_oct(int64 value, int32 neg_bits) {
|
|
||||||
|
|
||||||
static int32 i, i2, i3, x, x2, neg;
|
|
||||||
static int64 value2;
|
|
||||||
static qbs *str;
|
|
||||||
|
|
||||||
str = qbs_new(22, 1);
|
|
||||||
|
|
||||||
// negative?
|
|
||||||
if ((value >> 63) & 1)
|
|
||||||
neg = 1;
|
|
||||||
else
|
|
||||||
neg = 0;
|
|
||||||
|
|
||||||
// calc. most significant bit
|
|
||||||
i2 = 0;
|
|
||||||
value2 = value;
|
|
||||||
if (neg) {
|
|
||||||
for (i = 1; i <= 64; i++) {
|
|
||||||
if (!(value2 & 1))
|
|
||||||
i2 = i;
|
|
||||||
value2 >>= 1;
|
|
||||||
}
|
|
||||||
if (i2 >= neg_bits) {
|
|
||||||
// doesn't fit in neg_bits, so expand to next 16/32/64 boundary
|
|
||||||
i3 = 64;
|
|
||||||
if (i2 < 32)
|
|
||||||
i3 = 32;
|
|
||||||
if (i2 < 16)
|
|
||||||
i3 = 16;
|
|
||||||
i2 = i3;
|
|
||||||
} else
|
|
||||||
i2 = neg_bits;
|
|
||||||
} else {
|
|
||||||
for (i = 1; i <= 64; i++) {
|
|
||||||
if (value2 & 1)
|
|
||||||
i2 = i;
|
|
||||||
value2 >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!i2) {
|
|
||||||
str->chr[0] = 48;
|
|
||||||
str->len = 1;
|
|
||||||
return str;
|
|
||||||
} //"0"
|
|
||||||
|
|
||||||
// calc. number of characters required in i3
|
|
||||||
i3 = i2 / 3;
|
|
||||||
if ((i3 * 3) != i2)
|
|
||||||
i3++;
|
|
||||||
|
|
||||||
// build string
|
|
||||||
str->len = i3;
|
|
||||||
i3--;
|
|
||||||
x = 0;
|
|
||||||
x2 = 0;
|
|
||||||
for (i = 1; i <= i2; i++) {
|
|
||||||
if (value & 1)
|
|
||||||
x2 |= (1 << x);
|
|
||||||
value >>= 1;
|
|
||||||
x++;
|
|
||||||
if (x == 3) {
|
|
||||||
str->chr[i3--] = x2 + 48;
|
|
||||||
x2 = 0;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (x)
|
|
||||||
str->chr[i3] = x2 + 48;
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: QBASIC uses 11 oct digits for SINGLE/DOUBLE or generates "OVERFLOW" if this range is exceeded
|
|
||||||
// QB64 uses 11 oct digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
|
||||||
// it uses up to 22 oct digits before generating an "OVERFLOW" error
|
|
||||||
// performs overflow check before calling func_oct
|
|
||||||
qbs *func_oct_float(long double value) {
|
|
||||||
static qbs *str;
|
|
||||||
static int64 ivalue;
|
|
||||||
static int64 uivalue;
|
|
||||||
// ref: uint64 0-18446744073709551615
|
|
||||||
// int64 \969223372036854775808 to 9223372036854775807
|
|
||||||
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
|
||||||
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
|
||||||
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
|
||||||
str = qbs_new(0, 1);
|
|
||||||
error(6); // Overflow
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (value >= 0) {
|
|
||||||
uivalue = qbr_longdouble_to_uint64(value);
|
|
||||||
ivalue = uivalue;
|
|
||||||
} else {
|
|
||||||
ivalue = qbr(value);
|
|
||||||
}
|
|
||||||
return func_oct(ivalue, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
qbs *func_hex(int64 value, int32 neg_size) {
|
|
||||||
// note: negative int64 values can be treated as positive uint64 values (and vise versa)
|
|
||||||
|
|
||||||
static int32 i, i2, i3, x, neg;
|
|
||||||
static int64 value2;
|
|
||||||
static qbs *str;
|
|
||||||
|
|
||||||
str = qbs_new(16, 1);
|
|
||||||
|
|
||||||
value2 = value;
|
|
||||||
i2 = 0;
|
|
||||||
i3 = 0;
|
|
||||||
for (i = 1; i <= 16; i++) {
|
|
||||||
if (value2 & 15)
|
|
||||||
i2 = i; // most significant digit of positive value
|
|
||||||
if ((value2 & 15) != 15) {
|
|
||||||
i3 = i; // most significant digit of negative value
|
|
||||||
if ((((value2 & 8) == 0) && (i != 16)))
|
|
||||||
i3++; // for a negative number to fit into 4/8 characters, its top bit must be on
|
|
||||||
}
|
|
||||||
x = value2 & 15;
|
|
||||||
if (x > 9)
|
|
||||||
x += 55;
|
|
||||||
else
|
|
||||||
x += 48;
|
|
||||||
str->chr[16 - i] = x;
|
|
||||||
value2 >>= 4;
|
|
||||||
}
|
|
||||||
if (!i2) {
|
|
||||||
str->chr[0] = 48;
|
|
||||||
str->len = 1;
|
|
||||||
return str;
|
|
||||||
} //"0"
|
|
||||||
|
|
||||||
// negative?
|
|
||||||
if ((value >> 63) & 1)
|
|
||||||
neg = 1;
|
|
||||||
else
|
|
||||||
neg = 0;
|
|
||||||
|
|
||||||
// change i2 from sig-digits to string-output-digits
|
|
||||||
if (neg) {
|
|
||||||
if (i3 <= neg_size) {
|
|
||||||
i2 = neg_size; // extend to minimum character size
|
|
||||||
} else {
|
|
||||||
// didn't fit in recommended size, expand to either 4, 8 or 16 appropriately
|
|
||||||
i2 = 16;
|
|
||||||
if (i3 <= 8)
|
|
||||||
i2 = 8;
|
|
||||||
if (i3 <= 4)
|
|
||||||
i2 = 4;
|
|
||||||
}
|
|
||||||
} // neg
|
|
||||||
|
|
||||||
// adjust string to the left to remove unnecessary characters
|
|
||||||
if (i2 != 16) {
|
|
||||||
memmove(str->chr, str->chr + (16 - i2), i2);
|
|
||||||
str->len = i2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: QBASIC uses 8 hex digits for SINGLE/DOUBLE or generates "OVERFLOW" if this range is exceeded
|
|
||||||
// QB64 uses 8 hex digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
|
||||||
// it uses up to 16 hex digits before generating an "OVERFLOW" error
|
|
||||||
// performs overflow check before calling func_hex
|
|
||||||
qbs *func_hex_float(long double value) {
|
|
||||||
static qbs *str;
|
|
||||||
static int64 ivalue;
|
|
||||||
static int64 uivalue;
|
|
||||||
// ref: uint64 0-18446744073709551615
|
|
||||||
// int64 \969223372036854775808 to 9223372036854775807
|
|
||||||
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
|
||||||
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
|
||||||
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
|
||||||
str = qbs_new(0, 1);
|
|
||||||
error(6); // Overflow
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
if (value >= 0) {
|
|
||||||
uivalue = qbr_longdouble_to_uint64(value);
|
|
||||||
ivalue = uivalue;
|
|
||||||
} else {
|
|
||||||
ivalue = qbr(value);
|
|
||||||
}
|
|
||||||
return func_hex(ivalue, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrszint func_lbound(ptrszint *array, int32 index, int32 num_indexes) {
|
ptrszint func_lbound(ptrszint *array, int32 index, int32 num_indexes) {
|
||||||
if ((index < 1) || (index > num_indexes) || ((array[2] & 1) == 0)) {
|
if ((index < 1) || (index > num_indexes) || ((array[2] & 1) == 0)) {
|
||||||
|
@ -18810,6 +18537,7 @@ qbs *func_input(int32 n, int32 i, int32 passed) {
|
||||||
|
|
||||||
// RANDOM (todo)
|
// RANDOM (todo)
|
||||||
|
|
||||||
|
return str;
|
||||||
} else {
|
} else {
|
||||||
// keyboard/piped
|
// keyboard/piped
|
||||||
// For extended-two-byte character codes, only the first, CHR$(0), is returned and counts a 1 byte
|
// For extended-two-byte character codes, only the first, CHR$(0), is returned and counts a 1 byte
|
||||||
|
@ -23984,6 +23712,7 @@ int32 connection_new(int32 method, qbs *info_in, int32 value) {
|
||||||
|
|
||||||
} //_OPENCONNECTION
|
} //_OPENCONNECTION
|
||||||
|
|
||||||
|
return -1;
|
||||||
} // connection_new
|
} // connection_new
|
||||||
|
|
||||||
// network prototype:
|
// network prototype:
|
||||||
|
|
|
@ -11,6 +11,7 @@ libqb-objs-y += $(PATH_LIBQB)/src/datetime.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/error_handle.o
|
libqb-objs-y += $(PATH_LIBQB)/src/error_handle.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/gfs.o
|
libqb-objs-y += $(PATH_LIBQB)/src/gfs.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/qblist.o
|
libqb-objs-y += $(PATH_LIBQB)/src/qblist.o
|
||||||
|
libqb-objs-y += $(PATH_LIBQB)/src/hexoctbin.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/mem.o
|
libqb-objs-y += $(PATH_LIBQB)/src/mem.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/math.o
|
libqb-objs-y += $(PATH_LIBQB)/src/math.o
|
||||||
libqb-objs-y += $(PATH_LIBQB)/src/rounding.o
|
libqb-objs-y += $(PATH_LIBQB)/src/rounding.o
|
||||||
|
|
12
internal/c/libqb/include/hexoctbin.h
Normal file
12
internal/c/libqb/include/hexoctbin.h
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "qbs.h"
|
||||||
|
|
||||||
|
qbs *func__bin(int64_t value, int32_t neg_bits);
|
||||||
|
qbs *func__bin_float(long double value);
|
||||||
|
qbs *func_oct(int64_t value, int32_t neg_bits);
|
||||||
|
qbs *func_oct_float(long double value);
|
||||||
|
qbs *func_hex(int64_t value, int32_t neg_size);
|
||||||
|
qbs *func_hex_float(long double value);
|
285
internal/c/libqb/src/hexoctbin.cpp
Normal file
285
internal/c/libqb/src/hexoctbin.cpp
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
|
||||||
|
#include "libqb-common.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "rounding.h"
|
||||||
|
#include "qbs.h"
|
||||||
|
#include "hexoctbin.h"
|
||||||
|
|
||||||
|
qbs *func__bin(int64_t value, int32_t neg_bits) {
|
||||||
|
static int32_t i, i2, i3, neg;
|
||||||
|
static int64_t value2;
|
||||||
|
static qbs *str;
|
||||||
|
|
||||||
|
str = qbs_new(64, 1);
|
||||||
|
|
||||||
|
// negative?
|
||||||
|
if ((value >> 63) & 1)
|
||||||
|
neg = 1;
|
||||||
|
else
|
||||||
|
neg = 0;
|
||||||
|
|
||||||
|
// calc. most significant bit
|
||||||
|
i2 = 0;
|
||||||
|
value2 = value;
|
||||||
|
if (neg) {
|
||||||
|
for (i = 1; i <= 64; i++) {
|
||||||
|
if (!(value2 & 1))
|
||||||
|
i2 = i;
|
||||||
|
value2 >>= 1;
|
||||||
|
}
|
||||||
|
if (i2 >= neg_bits) {
|
||||||
|
// doesn't fit in neg_bits, so expand to next 16/32/64 boundary
|
||||||
|
i3 = 64;
|
||||||
|
if (i2 < 32)
|
||||||
|
i3 = 32;
|
||||||
|
if (i2 < 16)
|
||||||
|
i3 = 16;
|
||||||
|
i2 = i3;
|
||||||
|
} else
|
||||||
|
i2 = neg_bits;
|
||||||
|
} else {
|
||||||
|
for (i = 1; i <= 64; i++) {
|
||||||
|
if (value2 & 1)
|
||||||
|
i2 = i;
|
||||||
|
value2 >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i2) {
|
||||||
|
str->chr[0] = 48;
|
||||||
|
str->len = 1;
|
||||||
|
return str;
|
||||||
|
} //"0"
|
||||||
|
|
||||||
|
// calc. number of characters required in i3
|
||||||
|
i3 = i2; // equal for BIN$ because one bit = one char
|
||||||
|
|
||||||
|
// build string
|
||||||
|
str->len = i3;
|
||||||
|
i3--;
|
||||||
|
for (i = 1; i <= i2; i++) {
|
||||||
|
str->chr[i3--] = (value & 1) + 48;
|
||||||
|
value >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: QBASIC doesn't have a BIN$ function
|
||||||
|
// QB64 uses 32 bin digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
||||||
|
// it uses up to 64 bin digits before generating an "OVERFLOW" error
|
||||||
|
// performs overflow check before calling func__bin
|
||||||
|
qbs *func__bin_float(long double value) {
|
||||||
|
static qbs *str;
|
||||||
|
static int64_t ivalue;
|
||||||
|
static int64_t uivalue;
|
||||||
|
// ref: uint64 0-18446744073709551615
|
||||||
|
// int64 \969223372036854775808 to 9223372036854775807
|
||||||
|
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
||||||
|
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
||||||
|
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
||||||
|
str = qbs_new(0, 1);
|
||||||
|
error(6); // Overflow
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if (value >= 0) {
|
||||||
|
uivalue = qbr_longdouble_to_uint64(value);
|
||||||
|
ivalue = uivalue;
|
||||||
|
} else {
|
||||||
|
ivalue = qbr(value);
|
||||||
|
}
|
||||||
|
return func__bin(ivalue, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
qbs *func_oct(int64_t value, int32_t neg_bits) {
|
||||||
|
|
||||||
|
static int32_t i, i2, i3, x, x2, neg;
|
||||||
|
static int64_t value2;
|
||||||
|
static qbs *str;
|
||||||
|
|
||||||
|
str = qbs_new(22, 1);
|
||||||
|
|
||||||
|
// negative?
|
||||||
|
if ((value >> 63) & 1)
|
||||||
|
neg = 1;
|
||||||
|
else
|
||||||
|
neg = 0;
|
||||||
|
|
||||||
|
// calc. most significant bit
|
||||||
|
i2 = 0;
|
||||||
|
value2 = value;
|
||||||
|
if (neg) {
|
||||||
|
for (i = 1; i <= 64; i++) {
|
||||||
|
if (!(value2 & 1))
|
||||||
|
i2 = i;
|
||||||
|
value2 >>= 1;
|
||||||
|
}
|
||||||
|
if (i2 >= neg_bits) {
|
||||||
|
// doesn't fit in neg_bits, so expand to next 16/32/64 boundary
|
||||||
|
i3 = 64;
|
||||||
|
if (i2 < 32)
|
||||||
|
i3 = 32;
|
||||||
|
if (i2 < 16)
|
||||||
|
i3 = 16;
|
||||||
|
i2 = i3;
|
||||||
|
} else
|
||||||
|
i2 = neg_bits;
|
||||||
|
} else {
|
||||||
|
for (i = 1; i <= 64; i++) {
|
||||||
|
if (value2 & 1)
|
||||||
|
i2 = i;
|
||||||
|
value2 >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i2) {
|
||||||
|
str->chr[0] = 48;
|
||||||
|
str->len = 1;
|
||||||
|
return str;
|
||||||
|
} //"0"
|
||||||
|
|
||||||
|
// calc. number of characters required in i3
|
||||||
|
i3 = i2 / 3;
|
||||||
|
if ((i3 * 3) != i2)
|
||||||
|
i3++;
|
||||||
|
|
||||||
|
// build string
|
||||||
|
str->len = i3;
|
||||||
|
i3--;
|
||||||
|
x = 0;
|
||||||
|
x2 = 0;
|
||||||
|
for (i = 1; i <= i2; i++) {
|
||||||
|
if (value & 1)
|
||||||
|
x2 |= (1 << x);
|
||||||
|
value >>= 1;
|
||||||
|
x++;
|
||||||
|
if (x == 3) {
|
||||||
|
str->chr[i3--] = x2 + 48;
|
||||||
|
x2 = 0;
|
||||||
|
x = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x)
|
||||||
|
str->chr[i3] = x2 + 48;
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: QBASIC uses 11 oct digits for SINGLE/DOUBLE or generates "OVERFLOW" if this range is exceeded
|
||||||
|
// QB64 uses 11 oct digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
||||||
|
// it uses up to 22 oct digits before generating an "OVERFLOW" error
|
||||||
|
// performs overflow check before calling func_oct
|
||||||
|
qbs *func_oct_float(long double value) {
|
||||||
|
static qbs *str;
|
||||||
|
static int64_t ivalue;
|
||||||
|
static int64_t uivalue;
|
||||||
|
// ref: uint64 0-18446744073709551615
|
||||||
|
// int64 \969223372036854775808 to 9223372036854775807
|
||||||
|
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
||||||
|
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
||||||
|
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
||||||
|
str = qbs_new(0, 1);
|
||||||
|
error(6); // Overflow
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if (value >= 0) {
|
||||||
|
uivalue = qbr_longdouble_to_uint64(value);
|
||||||
|
ivalue = uivalue;
|
||||||
|
} else {
|
||||||
|
ivalue = qbr(value);
|
||||||
|
}
|
||||||
|
return func_oct(ivalue, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
qbs *func_hex(int64_t value, int32_t neg_size) {
|
||||||
|
// note: negative int64 values can be treated as positive uint64 values (and vise versa)
|
||||||
|
|
||||||
|
static int32_t i, i2, i3, x, neg;
|
||||||
|
static int64_t value2;
|
||||||
|
static qbs *str;
|
||||||
|
|
||||||
|
str = qbs_new(16, 1);
|
||||||
|
|
||||||
|
value2 = value;
|
||||||
|
i2 = 0;
|
||||||
|
i3 = 0;
|
||||||
|
for (i = 1; i <= 16; i++) {
|
||||||
|
if (value2 & 15)
|
||||||
|
i2 = i; // most significant digit of positive value
|
||||||
|
if ((value2 & 15) != 15) {
|
||||||
|
i3 = i; // most significant digit of negative value
|
||||||
|
if ((((value2 & 8) == 0) && (i != 16)))
|
||||||
|
i3++; // for a negative number to fit into 4/8 characters, its top bit must be on
|
||||||
|
}
|
||||||
|
x = value2 & 15;
|
||||||
|
if (x > 9)
|
||||||
|
x += 55;
|
||||||
|
else
|
||||||
|
x += 48;
|
||||||
|
str->chr[16 - i] = x;
|
||||||
|
value2 >>= 4;
|
||||||
|
}
|
||||||
|
if (!i2) {
|
||||||
|
str->chr[0] = 48;
|
||||||
|
str->len = 1;
|
||||||
|
return str;
|
||||||
|
} //"0"
|
||||||
|
|
||||||
|
// negative?
|
||||||
|
if ((value >> 63) & 1)
|
||||||
|
neg = 1;
|
||||||
|
else
|
||||||
|
neg = 0;
|
||||||
|
|
||||||
|
// change i2 from sig-digits to string-output-digits
|
||||||
|
if (neg) {
|
||||||
|
if (i3 <= neg_size) {
|
||||||
|
i2 = neg_size; // extend to minimum character size
|
||||||
|
} else {
|
||||||
|
// didn't fit in recommended size, expand to either 4, 8 or 16 appropriately
|
||||||
|
i2 = 16;
|
||||||
|
if (i3 <= 8)
|
||||||
|
i2 = 8;
|
||||||
|
if (i3 <= 4)
|
||||||
|
i2 = 4;
|
||||||
|
}
|
||||||
|
} // neg
|
||||||
|
|
||||||
|
// adjust string to the left to remove unnecessary characters
|
||||||
|
if (i2 != 16) {
|
||||||
|
memmove(str->chr, str->chr + (16 - i2), i2);
|
||||||
|
str->len = i2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: QBASIC uses 8 hex digits for SINGLE/DOUBLE or generates "OVERFLOW" if this range is exceeded
|
||||||
|
// QB64 uses 8 hex digits for SINGLE/DOUBLE/FLOAT but if this range is exceeded
|
||||||
|
// it uses up to 16 hex digits before generating an "OVERFLOW" error
|
||||||
|
// performs overflow check before calling func_hex
|
||||||
|
qbs *func_hex_float(long double value) {
|
||||||
|
static qbs *str;
|
||||||
|
static int64_t ivalue;
|
||||||
|
static int64_t uivalue;
|
||||||
|
// ref: uint64 0-18446744073709551615
|
||||||
|
// int64 \969223372036854775808 to 9223372036854775807
|
||||||
|
if ((value >= 9.223372036854776E18) || (value <= -9.223372036854776E18)) {
|
||||||
|
// note: ideally, the following line would be used, however, qbr_longdouble_to_uint64 just does the same as qbr
|
||||||
|
// if ((value>=1.844674407370956E19)||(value<=-9.223372036854776E18)){
|
||||||
|
str = qbs_new(0, 1);
|
||||||
|
error(6); // Overflow
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
if (value >= 0) {
|
||||||
|
uivalue = qbr_longdouble_to_uint64(value);
|
||||||
|
ivalue = uivalue;
|
||||||
|
} else {
|
||||||
|
ivalue = qbr(value);
|
||||||
|
}
|
||||||
|
return func_hex(ivalue, 8);
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include "hexoctbin.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "qbmath.h"
|
#include "qbmath.h"
|
||||||
#include "qbs.h"
|
#include "qbs.h"
|
||||||
|
@ -352,12 +353,6 @@ extern void sub_graphics_put(float x1f, float y1f, void *element, int32 option,
|
||||||
extern int32 func_csrlin();
|
extern int32 func_csrlin();
|
||||||
extern int32 func_pos(int32 ignore);
|
extern int32 func_pos(int32 ignore);
|
||||||
extern void sub_sleep(int32 seconds, int32 passed);
|
extern void sub_sleep(int32 seconds, int32 passed);
|
||||||
extern qbs *func__bin(int64 value, int32 neg_bits);
|
|
||||||
extern qbs *func__bin_float(long double value);
|
|
||||||
extern qbs *func_oct(int64 value, int32 neg_bits);
|
|
||||||
extern qbs *func_oct_float(long double value);
|
|
||||||
extern qbs *func_hex(int64 value, int32 neg_size);
|
|
||||||
extern qbs *func_hex_float(long double value);
|
|
||||||
extern ptrszint func_lbound(ptrszint *array, int32 index, int32 num_indexes);
|
extern ptrszint func_lbound(ptrszint *array, int32 index, int32 num_indexes);
|
||||||
extern ptrszint func_ubound(ptrszint *array, int32 index, int32 num_indexes);
|
extern ptrszint func_ubound(ptrszint *array, int32 index, int32 num_indexes);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue