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

[17_1] Add hanzi_nr to convert numbers to Chinese numerals #202

Merged
merged 5 commits into from
Oct 30, 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
103 changes: 103 additions & 0 deletions Kernel/Types/analyze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,109 @@ fnsymbol_nr (int nr) {
return r;
}

// 0 should not be used as index of this array, or bug occurs. because digit 0
// is handled specially according to position of digit.
static string chars_han[10]= {
"<unspecified>", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
jingkaimori marked this conversation as resolved.
Show resolved Hide resolved

string
hanzi_sub (int16_t nr, bool leading_zero) {
short thousand= (nr % 10000) / 1000, hundred= (nr % 1000) / 100,
ten= (nr % 100) / 10, one= nr % 10;
short cases= (leading_zero << 4) | ((thousand == 0) << 3) |
((hundred == 0) << 2) | ((ten == 0) << 1) | (one == 0);
switch (cases) {
case 0x0:
case 0x10:
return chars_han[thousand] * "千" * chars_han[hundred] * "百" *
chars_han[ten] * "十" * chars_han[one];
case 0x1:
case 0x11:
return chars_han[thousand] * "千" * chars_han[hundred] * "百" *
chars_han[ten] * "十";
case 0x2:
case 0x12:
return chars_han[thousand] * "千" * chars_han[hundred] * "百零" *
chars_han[one];
case 0x3:
case 0x13:
return chars_han[thousand] * "千" * chars_han[hundred] * "百";
case 0x4:
case 0x14:
return chars_han[thousand] * "千零" * chars_han[ten] * "十" *
chars_han[one];
case 0x5:
case 0x15:
return chars_han[thousand] * "千零" * chars_han[ten] * "十";
case 0x6:
case 0x16:
return chars_han[thousand] * "千零" * chars_han[one];
case 0x7:
case 0x17:
return chars_han[thousand] * "千";
case 0x8:
return chars_han[hundred] * "百" * chars_han[ten] * "十" * chars_han[one];
case 0x18:
return "零" * chars_han[hundred] * "百" * chars_han[ten] * "十" *
chars_han[one];
case 0x9:
return chars_han[hundred] * "百" * chars_han[ten] * "十";
case 0x19:
return "零" * chars_han[hundred] * "百" * chars_han[ten] * "十";
case 0xA:
return chars_han[hundred] * "百零" * chars_han[one];
case 0x1A:
return "零" * chars_han[hundred] * "百零" * chars_han[one];
case 0xB:
return chars_han[hundred] * "百";
case 0x1B:
return "零" * chars_han[hundred] * "百";
case 0xC:
if (ten == 1) {
return "十" * chars_han[one];
}
else {
return chars_han[ten] * "十" * chars_han[one];
}
case 0x1C:
return "零" * chars_han[ten] * "十" * chars_han[one];
case 0xD:
if (ten == 1) {
return "十";
}
else {
return chars_han[ten] * "十";
}
case 0x1D:
return "零" * chars_han[ten] * "十";
case 0xE:
return chars_han[one];
case 0x1E:
return "零" * chars_han[one];
case 0xF:
case 0x1F:
return "";
default:
return "<unspecified>" * as_string (cases);
}
}

string
hanzi_nr (int32_t nr) {
if (nr == 0) return "零";
if (nr == 0x80000000) return "负二十一亿四千七百四十八万三千六百四十八";
if (nr < 0) return "负" * hanzi_nr (-nr);
if (nr >= 100000000) {
return hanzi_sub (nr / 100000000, false) * "亿" *
hanzi_sub ((nr / 10000) % 10000, true) * "万" *
hanzi_sub (nr % 10000, true);
}
if (nr >= 10000) {
return hanzi_sub (nr / 10000, false) * "万" * hanzi_sub (nr % 10000, true);
}
return hanzi_sub (nr, false);
}

/******************************************************************************
* Conversions to and from hexadecimal
******************************************************************************/
Expand Down
8 changes: 8 additions & 0 deletions Kernel/Types/analyze.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,14 @@ string Alpha_nr (int nr);
*/
string fnsymbol_nr (int nr);

/**
* @brief Generates a Chinese numeral for a given integer.
*
* @param nr The integer to be converted to a Chinese numeral.
* @return A string representing the Chinese numeral.
*/
string hanzi_nr (int32_t nr);

/**
* @brief Converts an integer to a hexadecimal string.
*
Expand Down
26 changes: 26 additions & 0 deletions tests/Kernel/Types/analyze_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,29 @@ TEST_CASE ("replace") {
CHECK_EQ (replace ("a-b", "-", "_") == "a_b", true);
CHECK_EQ (replace ("a-b-c", "-", "_") == "a_b_c", true);
}

TEST_CASE ("hanzi_nr") {
string_eq (hanzi_nr (-1605), "负一千六百零五");
string_eq (hanzi_nr (0), "零");
string_eq (hanzi_nr (1), "一");
string_eq (hanzi_nr (10), "十");
string_eq (hanzi_nr (11), "十一");
string_eq (hanzi_nr (42), "四十二");
string_eq (hanzi_nr (90), "九十");
string_eq (hanzi_nr (100), "一百");
string_eq (hanzi_nr (102), "一百零二");
string_eq (hanzi_nr (110), "一百一十");
string_eq (hanzi_nr (123), "一百二十三");
string_eq (hanzi_nr (1000), "一千");
string_eq (hanzi_nr (1001), "一千零一");
string_eq (hanzi_nr (1024), "一千零二十四");
string_eq (hanzi_nr (1030), "一千零三十");
string_eq (hanzi_nr (1600), "一千六百");
string_eq (hanzi_nr (1605), "一千六百零五");
string_eq (hanzi_nr (10000), "一万");
string_eq (hanzi_nr (10001), "一万零一");
string_eq (hanzi_nr (153457), "十五万三千四百五十七");
string_eq (hanzi_nr (300153457), "三亿零一十五万三千四百五十七");
da-liii marked this conversation as resolved.
Show resolved Hide resolved
string_eq (hanzi_nr (0x7FFFFFFF), "二十一亿四千七百四十八万三千六百四十七");
string_eq (hanzi_nr (0x80000000), "负二十一亿四千七百四十八万三千六百四十八");
}
3 changes: 2 additions & 1 deletion xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ target("liblolly") do
set_kind("static")
set_languages("c++17")
set_policy("check.auto_ignore_flags", false)
set_encodings("utf-8")
my_configvar_check()

set_basename("lolly")
Expand Down Expand Up @@ -190,7 +191,7 @@ function add_test_target(filepath)
end

if is_plat("windows") then
add_cxxflags("/utf-8")
set_encodings("utf-8")
add_ldflags("/LTCG")
end

Expand Down
Loading