say.c: Fix cents off-by-one due to floating point rounding.

Some of the money announcements can be off by one cent,
due to the use of floating point in the money calculations,
which is bad for obvious reasons.

This replaces floating point with simple string parsing
to ensure the cents value is converted accurately.

Resolves: #525
This commit is contained in:
Naveen Albert
2024-01-10 08:26:05 -05:00
parent c276ae11e0
commit b836f9c01c
2 changed files with 106 additions and 13 deletions

View File

@@ -356,6 +356,14 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(.42,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/40&digits/2&cents") != 0) {
ast_test_status_update(test, "SAYFILES(.42,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(1.00,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/1&letters/dollar") != 0) {
@@ -380,6 +388,14 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.42,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/40&digits/2&cents") != 0) {
@@ -388,6 +404,63 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/5&cents") != 0) {
ast_test_status_update(test, "SAYFILES(2.05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.051,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/5&cents") != 0) {
ast_test_status_update(test, "SAYFILES(2.051,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
/* Invalid amounts */
ast_str_set(&expr, 0, "${SAYFILES(blah,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/0&cents") != 0) {
ast_test_status_update(test, "SAYFILES(blah,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2blah.05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2blah.05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.-05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2.-05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2. 05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2. 05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(. 05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/0&cents") != 0) {
ast_test_status_update(test, "SAYFILES(. 05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_free(expr);
ast_free(result);