Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix atoi #5

Merged
merged 2 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions include/c-stdlib/src/printf_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,26 @@ static inline unsigned int _strnlen_s(const char *str, size_t maxsize) {
static inline bool _is_digit(char ch) { return (ch >= '0') && (ch <= '9'); }

// internal ASCII string to unsigned int conversion
unsigned int atoi(const char **str) {
unsigned int _atoi(const char **str) {
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}

int atoi(const char *str) {
if (str[0] == '+') {
const char *sub = str + 1;
return +_atoi(&sub);
}
if (str[0] == '-') {
const char *sub = str + 1;
return -_atoi(&sub);
}
return _atoi(&str);
}

// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len,
unsigned int width, unsigned int flags) {
Expand Down Expand Up @@ -685,7 +697,7 @@ static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = atoi(&format);
width = _atoi(&format);
} else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
Expand All @@ -703,7 +715,7 @@ static int _vsnprintf(out_fct_type out, char *buffer, const size_t maxlen, const
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = atoi(&format);
precision = _atoi(&format);
} else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
Expand Down
1 change: 1 addition & 0 deletions tests/basic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ qjs-tests:
$(call run,test_closure.js)
$(call run,test_builtin.js)
$(call run,test_bignum.js)
$(call run,test_float.js)

log:
$(CKB-DEBUGGER) --bin $(BIN_PATH) -- -e "console.log(scriptArgs[0], scriptArgs[1]);" hello world
Expand Down
37 changes: 18 additions & 19 deletions tests/basic/test_bignum.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ function test_bigint1()

r = 1n << 31n;
assert(r, 2147483648n, "1 << 31n === 2147483648n");

r = 1n << 32n;
assert(r, 4294967296n, "1 << 32n === 4294967296n");
}
Expand Down Expand Up @@ -150,7 +150,7 @@ function test_bigint_ext()
function test_bigfloat()
{
var e, a, b, sqrt2;

assert(typeof 1n === "bigint");
assert(typeof 1l === "bigfloat");
assert(1 == 1.0l);
Expand All @@ -164,7 +164,7 @@ function test_bigfloat()

test_less(2.1, 3l);
// test_eq(Math.sqrt(9), 3l);

test_less(2n, 3l);
test_eq(3n, 3l);

Expand All @@ -174,7 +174,7 @@ function test_bigfloat()
// assert(a === BigFloat.parseFloat("0x1.6a09e667f3bcc908b2fb1366ea957d3e", 0, e));
// assert(e.inexact === true);
// assert(BigFloat.fpRound(a) == 0x1.6a09e667f3bcc908b2fb1366ea95l);

// b = BigFloatEnv.setPrec(BigFloat.sqrt.bind(null, 2), 128);
// assert(a === b);

Expand All @@ -188,7 +188,7 @@ function test_bigfloat()
assert(BigFloat.exp(0.2l) === 1.2214027581601698339210719946396742l);
assert(BigFloat.log(3l) === 1.0986122886681096913952452369225256l);
assert(BigFloat.pow(2.1l, 1.6l) === 3.277561666451861947162828744873745l);

assert(BigFloat.sin(-1l) === -0.841470984807896506652502321630299l);
assert(BigFloat.cos(1l) === 0.5403023058681397174009366074429766l);
assert(BigFloat.tan(0.1l) === 0.10033467208545054505808004578111154l);
Expand Down Expand Up @@ -241,15 +241,15 @@ function test_bigdecimal()
assert(1m !== 2m);
test_less(1m, 2m);
test_eq(2m, 2m);

test_less(1, 2m);

// test_less(1.1, 2m);
// test_eq(Math.sqrt(4), 2m);

test_less(2n, 3m);
test_eq(3n, 3m);

assert(BigDecimal("1234.1") === 1234.1m);
assert(BigDecimal(" 1234.1") === 1234.1m);
assert(BigDecimal(" 1234.1 ") === 1234.1m);
Expand All @@ -271,7 +271,7 @@ function test_bigdecimal()
assert(1234.5m ** 3m === 1881365963.625m);
assertThrows(RangeError, () => { 2m ** 3.1m } );
assertThrows(RangeError, () => { 2m ** -3m } );

// assert(BigDecimal.sqrt(2m,
// { roundingMode: "half-even",
// maximumSignificantDigits: 4 }) === 1.414m);
Expand All @@ -281,7 +281,7 @@ function test_bigdecimal()
// assert(BigDecimal.sqrt(0.002m,
// { roundingMode: "half-even",
// maximumFractionDigits: 3 }) === 0.045m);

assert(BigDecimal.round(3.14159m,
{ roundingMode: "half-even",
maximumFractionDigits: 3 }) === 3.142m);
Expand All @@ -308,15 +308,14 @@ function test_bigdecimal()

/* string conversion */
assert((1234.125m).toString(), "1234.125");
// TODO:
// assert((1234.125m).toFixed(2), "1234.13");
// assert((1234.125m).toFixed(2, "down"), "1234.12");
// assert((1234.125m).toExponential(), "1.234125e+3");
// assert((1234.125m).toExponential(5), "1.23413e+3");
// assert((1234.125m).toExponential(5, "down"), "1.23412e+3");
// assert((1234.125m).toPrecision(6), "1234.13");
// assert((1234.125m).toPrecision(6, "down"), "1234.12");
// assert((-1234.125m).toPrecision(6, "floor"), "-1234.13");
assert((1234.125m).toFixed(2), "1234.13");
assert((1234.125m).toFixed(2, "down"), "1234.12");
assert((1234.125m).toExponential(), "1.234125e+3");
assert((1234.125m).toExponential(5), "1.23413e+3");
assert((1234.125m).toExponential(5, "down"), "1.23412e+3");
assert((1234.125m).toPrecision(6), "1234.13");
assert((1234.125m).toPrecision(6, "down"), "1234.12");
assert((-1234.125m).toPrecision(6, "floor"), "-1234.13");
}
test_bigint1();
test_bigint2();
Expand Down
21 changes: 21 additions & 0 deletions tests/basic/test_float.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use strict";

function assert(actual, expected, message) {
if (arguments.length == 1)
expected = true;

if (actual == expected)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use "==="

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a BUG in the code, because during testing I found that -1.1.toString() == "-1.100000" passed, but -1.1.toString() === "-1.100000" failed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to find the reason in another PR

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qjs > let b = -1.1.toString()
undefined
qjs > typeof(b)
"number"

return;

throw Error("assertion failed: got |" + actual + "|" +
", expected |" + expected + "|" +
(message ? " (" + message + ")" : ""));
}

function test_to_string() {
assert(1.1.toString(), "1.1")
assert(-1.1.toString(), "-1.100000")
assert(3.14159265354.toString(), "3.1415926540000000")
}

test_to_string()