Japanese reading of an integerCtCI 16.8: Integer to English phrase in C++Converting an integer number into its word representationInt extension for translating integer to plain EnglishInteger to English ConversionInteger to English challengeConvert an Integer number to readable format in JavaC++17 saturating integer (arithmetic) type libraryMy implementation of a for_each function that traverses a std::container by some step size integer NOne-dimensional Japanese puzzleCtCI 16.8: Integer to English phrase in C++
50% portfolio in single stock, JPM - appropriate for 80 year old?
How do I experimentally measure the surface area of a rock?
What is a dropfile?
Bo Derek in texbook.tex?
Is it possible to use gases instead of liquids as fuel in a rocket engine?
How to determine the degree to which diminished seventh chords and half-diminished seventh chords belong in major scales?
find a condition on B,C so set difference is associative (AB)C=A(BC)
Which battle was the most lopsided result in terms of casualties?
Invalid time zone 'UTC'
Is it possible to get reverse life insurance?
A Star Trek book I read in the eighties, Kirk is shunned for destroying a civilization
Shoe shine shop model in Rust
Equality operator does not get defined for a custom spaceship operator implementation in C++20
How to present boolean options along with selecting exactly 1 of them as "primary"?
Black powder machine gun in an airplane
Why do Muslim refugees seek asylum in Europe and not in rich countries in the Middle East?
What feature could divide the world in two halves and what would be the climate implications?
Interview question: If correlation doesn't imply causation, how do you detect causation?
Can a professor do an internship?
What is the exact definition of an Adaptation under Creative Commons?
When the direction of a movement changes, is the object at rest at some time?
Should I report a security vulnerability?
Just bought HD650's with Scarlet 2i2 solo and it sounds too QUIET
Customize sysctl parameters by user
Japanese reading of an integer
CtCI 16.8: Integer to English phrase in C++Converting an integer number into its word representationInt extension for translating integer to plain EnglishInteger to English ConversionInteger to English challengeConvert an Integer number to readable format in JavaC++17 saturating integer (arithmetic) type libraryMy implementation of a for_each function that traverses a std::container by some step size integer NOne-dimensional Japanese puzzleCtCI 16.8: Integer to English phrase in C++
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;
$begingroup$
Inspired by CtCI 16.8: Integer to English phrase in C++, I wrote a program to show the Japanese reading of an integer (positive, negative, or zero). The Japanese is written in Hepburn romanization to avoid encoding problems. Also, traditional Hepburn is used to avoid macrons.
Unlike English, Japanese has sound changes when two words come together. The details are given at the end of the question.
The program handles integers $n$ in the range $-2^63 le n < 2^63$.
Code
/**
* Integer to Japanese reading
*
* Japanese reading is written in Hepburn Roomaji. Traditional
* Hepburn is used to avoid the need of macrons.
*/
#include <cassert>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
using number_t = std::int_fast64_t;
const std::vector<std::string> magnitudes =
"", "man", "oku", "choo", "kee",
;
const std::vector<std::string> thousands =
"", "sen", "nisen", "sanzen", "yonsen",
"gosen", "rokusen", "nanasen", "hassen", "kyuusen",
;
const std::vector<std::string> hundreds =
"", "hyaku", "nihyaku", "sanbyaku", "yonhyaku",
"gohyaku", "roppyaku", "nanahyaku", "happyaku", "kyuuhyaku",
;
const std::vector<std::string> tens =
"", "juu", "nijuu", "sanjuu", "yonjuu",
"gojuu", "rokujuu", "nanajuu", "hachijuu", "kyuujuu",
;
const std::vector<std::string> ones =
"", "ichi", "ni", "san", "yon",
"go", "roku", "nana", "hachi", "kyuu",
;
// returns 10000^n
constexpr number_t magnitude(std::size_t n)
number_t result = 1;
while (n--)
result *= 10000;
return result;
constexpr bool is_vowel(char c)
switch (c)
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
return true;
default:
return false;
// joins two strings according to Japanese rules
void push(std::string& lhs, const std::string& rhs)
if (lhs.back() == 'n' && is_vowel(rhs.front()))
lhs += ''';
lhs += rhs;
// converts nonnegative numbers less than 10000
std::string group_name(number_t number)
assert(0 <= number && number < 10000);
std::string result = thousands[number / 1000];
number %= 1000;
push(result, hundreds[number / 100]);
number %= 100;
push(result, tens[number / 10]);
number %= 10;
push(result, ones[number]);
return result;
std::string to_Japanese(number_t number)
if (number == 0)
return "zero";
std::string result;
if (number < 0)
result = "mainasu";
number = -number;
number_t mag = magnitude(magnitudes.size() - 1);
for (std::size_t i = magnitudes.size(); i-- > 0; mag /= 10000)
if (auto group = number / mag; group > 0)
push(result, group_name(group));
push(result, magnitudes[i]);
number %= mag;
return result;
int main()
for (number_t number; std::cin >> number;)
std::cout << to_Japanese(number) << "n";
Example session
0
zero
1
ichi
2
ni
3
san
6789678967896789
rokusennanahyakuhachijuukyuuchoorokusennanahyakuhachijuukyuuokurokusennanahyakuhachijuukyuumanrokusennanahyakuhachijuukyuu
-1234567898765432
mainasusennihyakusanjuuyonchoogosenroppyakunanajuuhachiokukyuusenhappyakunanajuurokumangosen'yonhyakusanjuuni
Japanese numerals
(You can skip this part if you are familiar with Japanese.)
In the following table, red entries involve sound change.
beginarrayll
textNumber & textJapanese reading \
1 & text一 (ichi) \
2 & text二 (ni) \
3 & text三 (san) \
4 & text四 (yon) \
5 & text五 (go) \
6 & text六 (roku) \
7 & text七 (nana) \
8 & text八 (hachi) \
9 & text九 (kyuu) \
10 & text十 (juu) \
20 & text二十 (nijuu) \
30 & text三十 (sanjuu) \
40 & text四十 (yonjuu) \
50 & text五十 (gojuu) \
60 & text六十 (rokujuu) \
70 & text七十 (nanajuu) \
80 & text八十 (hachijuu) \
90 & text九十 (kyuujuu) \
100 & text百 (hyaku) \
200 & text二百 (nihyaku) \
300 & text三百 colorredtext(sanbyaku) \
400 & text四百 (yonhyaku) \
500 & text五百 (gohyaku) \
600 & text六百 colorredtext(roppyaku) \
700 & text七百 (nanahyaku) \
800 & text八百 colorredtext(happyaku) \
900 & text九百 (kyuuhyaku) \
1000 & text千 (sen) \
2000 & text二千 (nisen) \
3000 & text三千 colorredtext(sanzen) \
4000 & text四千 (yonsen) \
5000 & text五千 (gosen) \
6000 & text六千 (rokusen) \
7000 & text七千 (nanasen) \
8000 & text八千 colorredtext(hassen) \
9000 & text九千 (kyuusen) \
endarray
Larger numbers are considered the sums of smaller numbers. For example:
beginarrayccccccc
2019 & = & 2000 & + & 10 & + & 9 \
text二千十九 (nisenjuukyuu) & &
text二千 (nisen) & &
text十 (juu) & &
text九 (kyuu)
endarray
The missing hundred place is simply ignored.
Four digits are considered a group, unlike English, where three digits are a group. The group markers are:
beginarrayccc
10^4 & 10^8 & 10^12 & 10^16 \
text万 (man) & text億 (oku) & text兆 (choo) & text京 (kee)
endarray
For example, $1,2345,6789$ is read as 一億二千三百四十五万六千七百八十九 (ichioku nisensanbyakuyonjuugoman rokusennanahyakuhachijuukyuu). (The spaces are for ease of recognition only.) Note that 一 (ichi) is required before these group markers, unlike 十 (juu), 百 (hyaku), and 千 (sen).
0 is ゼロ (zero).
A negative integer $-n$ is read as マイナス (mainasu) followed by its absolute value $n$. For example, -5 is read as マイナス五 (mainasugo), because 5 is read as 五 (go).
When two syllables are joined, if the first syllable ends with "n" and the second starts with one of "aeiouy", then a separator ' is added between. For example, 1001 is 千一 (sen'ichi) and 1004 is 千四 (sen'yon).
c++ c++17 numbers-to-words
$endgroup$
add a comment
|
$begingroup$
Inspired by CtCI 16.8: Integer to English phrase in C++, I wrote a program to show the Japanese reading of an integer (positive, negative, or zero). The Japanese is written in Hepburn romanization to avoid encoding problems. Also, traditional Hepburn is used to avoid macrons.
Unlike English, Japanese has sound changes when two words come together. The details are given at the end of the question.
The program handles integers $n$ in the range $-2^63 le n < 2^63$.
Code
/**
* Integer to Japanese reading
*
* Japanese reading is written in Hepburn Roomaji. Traditional
* Hepburn is used to avoid the need of macrons.
*/
#include <cassert>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
using number_t = std::int_fast64_t;
const std::vector<std::string> magnitudes =
"", "man", "oku", "choo", "kee",
;
const std::vector<std::string> thousands =
"", "sen", "nisen", "sanzen", "yonsen",
"gosen", "rokusen", "nanasen", "hassen", "kyuusen",
;
const std::vector<std::string> hundreds =
"", "hyaku", "nihyaku", "sanbyaku", "yonhyaku",
"gohyaku", "roppyaku", "nanahyaku", "happyaku", "kyuuhyaku",
;
const std::vector<std::string> tens =
"", "juu", "nijuu", "sanjuu", "yonjuu",
"gojuu", "rokujuu", "nanajuu", "hachijuu", "kyuujuu",
;
const std::vector<std::string> ones =
"", "ichi", "ni", "san", "yon",
"go", "roku", "nana", "hachi", "kyuu",
;
// returns 10000^n
constexpr number_t magnitude(std::size_t n)
number_t result = 1;
while (n--)
result *= 10000;
return result;
constexpr bool is_vowel(char c)
switch (c)
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
return true;
default:
return false;
// joins two strings according to Japanese rules
void push(std::string& lhs, const std::string& rhs)
if (lhs.back() == 'n' && is_vowel(rhs.front()))
lhs += ''';
lhs += rhs;
// converts nonnegative numbers less than 10000
std::string group_name(number_t number)
assert(0 <= number && number < 10000);
std::string result = thousands[number / 1000];
number %= 1000;
push(result, hundreds[number / 100]);
number %= 100;
push(result, tens[number / 10]);
number %= 10;
push(result, ones[number]);
return result;
std::string to_Japanese(number_t number)
if (number == 0)
return "zero";
std::string result;
if (number < 0)
result = "mainasu";
number = -number;
number_t mag = magnitude(magnitudes.size() - 1);
for (std::size_t i = magnitudes.size(); i-- > 0; mag /= 10000)
if (auto group = number / mag; group > 0)
push(result, group_name(group));
push(result, magnitudes[i]);
number %= mag;
return result;
int main()
for (number_t number; std::cin >> number;)
std::cout << to_Japanese(number) << "n";
Example session
0
zero
1
ichi
2
ni
3
san
6789678967896789
rokusennanahyakuhachijuukyuuchoorokusennanahyakuhachijuukyuuokurokusennanahyakuhachijuukyuumanrokusennanahyakuhachijuukyuu
-1234567898765432
mainasusennihyakusanjuuyonchoogosenroppyakunanajuuhachiokukyuusenhappyakunanajuurokumangosen'yonhyakusanjuuni
Japanese numerals
(You can skip this part if you are familiar with Japanese.)
In the following table, red entries involve sound change.
beginarrayll
textNumber & textJapanese reading \
1 & text一 (ichi) \
2 & text二 (ni) \
3 & text三 (san) \
4 & text四 (yon) \
5 & text五 (go) \
6 & text六 (roku) \
7 & text七 (nana) \
8 & text八 (hachi) \
9 & text九 (kyuu) \
10 & text十 (juu) \
20 & text二十 (nijuu) \
30 & text三十 (sanjuu) \
40 & text四十 (yonjuu) \
50 & text五十 (gojuu) \
60 & text六十 (rokujuu) \
70 & text七十 (nanajuu) \
80 & text八十 (hachijuu) \
90 & text九十 (kyuujuu) \
100 & text百 (hyaku) \
200 & text二百 (nihyaku) \
300 & text三百 colorredtext(sanbyaku) \
400 & text四百 (yonhyaku) \
500 & text五百 (gohyaku) \
600 & text六百 colorredtext(roppyaku) \
700 & text七百 (nanahyaku) \
800 & text八百 colorredtext(happyaku) \
900 & text九百 (kyuuhyaku) \
1000 & text千 (sen) \
2000 & text二千 (nisen) \
3000 & text三千 colorredtext(sanzen) \
4000 & text四千 (yonsen) \
5000 & text五千 (gosen) \
6000 & text六千 (rokusen) \
7000 & text七千 (nanasen) \
8000 & text八千 colorredtext(hassen) \
9000 & text九千 (kyuusen) \
endarray
Larger numbers are considered the sums of smaller numbers. For example:
beginarrayccccccc
2019 & = & 2000 & + & 10 & + & 9 \
text二千十九 (nisenjuukyuu) & &
text二千 (nisen) & &
text十 (juu) & &
text九 (kyuu)
endarray
The missing hundred place is simply ignored.
Four digits are considered a group, unlike English, where three digits are a group. The group markers are:
beginarrayccc
10^4 & 10^8 & 10^12 & 10^16 \
text万 (man) & text億 (oku) & text兆 (choo) & text京 (kee)
endarray
For example, $1,2345,6789$ is read as 一億二千三百四十五万六千七百八十九 (ichioku nisensanbyakuyonjuugoman rokusennanahyakuhachijuukyuu). (The spaces are for ease of recognition only.) Note that 一 (ichi) is required before these group markers, unlike 十 (juu), 百 (hyaku), and 千 (sen).
0 is ゼロ (zero).
A negative integer $-n$ is read as マイナス (mainasu) followed by its absolute value $n$. For example, -5 is read as マイナス五 (mainasugo), because 5 is read as 五 (go).
When two syllables are joined, if the first syllable ends with "n" and the second starts with one of "aeiouy", then a separator ' is added between. For example, 1001 is 千一 (sen'ichi) and 1004 is 千四 (sen'yon).
c++ c++17 numbers-to-words
$endgroup$
add a comment
|
$begingroup$
Inspired by CtCI 16.8: Integer to English phrase in C++, I wrote a program to show the Japanese reading of an integer (positive, negative, or zero). The Japanese is written in Hepburn romanization to avoid encoding problems. Also, traditional Hepburn is used to avoid macrons.
Unlike English, Japanese has sound changes when two words come together. The details are given at the end of the question.
The program handles integers $n$ in the range $-2^63 le n < 2^63$.
Code
/**
* Integer to Japanese reading
*
* Japanese reading is written in Hepburn Roomaji. Traditional
* Hepburn is used to avoid the need of macrons.
*/
#include <cassert>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
using number_t = std::int_fast64_t;
const std::vector<std::string> magnitudes =
"", "man", "oku", "choo", "kee",
;
const std::vector<std::string> thousands =
"", "sen", "nisen", "sanzen", "yonsen",
"gosen", "rokusen", "nanasen", "hassen", "kyuusen",
;
const std::vector<std::string> hundreds =
"", "hyaku", "nihyaku", "sanbyaku", "yonhyaku",
"gohyaku", "roppyaku", "nanahyaku", "happyaku", "kyuuhyaku",
;
const std::vector<std::string> tens =
"", "juu", "nijuu", "sanjuu", "yonjuu",
"gojuu", "rokujuu", "nanajuu", "hachijuu", "kyuujuu",
;
const std::vector<std::string> ones =
"", "ichi", "ni", "san", "yon",
"go", "roku", "nana", "hachi", "kyuu",
;
// returns 10000^n
constexpr number_t magnitude(std::size_t n)
number_t result = 1;
while (n--)
result *= 10000;
return result;
constexpr bool is_vowel(char c)
switch (c)
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
return true;
default:
return false;
// joins two strings according to Japanese rules
void push(std::string& lhs, const std::string& rhs)
if (lhs.back() == 'n' && is_vowel(rhs.front()))
lhs += ''';
lhs += rhs;
// converts nonnegative numbers less than 10000
std::string group_name(number_t number)
assert(0 <= number && number < 10000);
std::string result = thousands[number / 1000];
number %= 1000;
push(result, hundreds[number / 100]);
number %= 100;
push(result, tens[number / 10]);
number %= 10;
push(result, ones[number]);
return result;
std::string to_Japanese(number_t number)
if (number == 0)
return "zero";
std::string result;
if (number < 0)
result = "mainasu";
number = -number;
number_t mag = magnitude(magnitudes.size() - 1);
for (std::size_t i = magnitudes.size(); i-- > 0; mag /= 10000)
if (auto group = number / mag; group > 0)
push(result, group_name(group));
push(result, magnitudes[i]);
number %= mag;
return result;
int main()
for (number_t number; std::cin >> number;)
std::cout << to_Japanese(number) << "n";
Example session
0
zero
1
ichi
2
ni
3
san
6789678967896789
rokusennanahyakuhachijuukyuuchoorokusennanahyakuhachijuukyuuokurokusennanahyakuhachijuukyuumanrokusennanahyakuhachijuukyuu
-1234567898765432
mainasusennihyakusanjuuyonchoogosenroppyakunanajuuhachiokukyuusenhappyakunanajuurokumangosen'yonhyakusanjuuni
Japanese numerals
(You can skip this part if you are familiar with Japanese.)
In the following table, red entries involve sound change.
beginarrayll
textNumber & textJapanese reading \
1 & text一 (ichi) \
2 & text二 (ni) \
3 & text三 (san) \
4 & text四 (yon) \
5 & text五 (go) \
6 & text六 (roku) \
7 & text七 (nana) \
8 & text八 (hachi) \
9 & text九 (kyuu) \
10 & text十 (juu) \
20 & text二十 (nijuu) \
30 & text三十 (sanjuu) \
40 & text四十 (yonjuu) \
50 & text五十 (gojuu) \
60 & text六十 (rokujuu) \
70 & text七十 (nanajuu) \
80 & text八十 (hachijuu) \
90 & text九十 (kyuujuu) \
100 & text百 (hyaku) \
200 & text二百 (nihyaku) \
300 & text三百 colorredtext(sanbyaku) \
400 & text四百 (yonhyaku) \
500 & text五百 (gohyaku) \
600 & text六百 colorredtext(roppyaku) \
700 & text七百 (nanahyaku) \
800 & text八百 colorredtext(happyaku) \
900 & text九百 (kyuuhyaku) \
1000 & text千 (sen) \
2000 & text二千 (nisen) \
3000 & text三千 colorredtext(sanzen) \
4000 & text四千 (yonsen) \
5000 & text五千 (gosen) \
6000 & text六千 (rokusen) \
7000 & text七千 (nanasen) \
8000 & text八千 colorredtext(hassen) \
9000 & text九千 (kyuusen) \
endarray
Larger numbers are considered the sums of smaller numbers. For example:
beginarrayccccccc
2019 & = & 2000 & + & 10 & + & 9 \
text二千十九 (nisenjuukyuu) & &
text二千 (nisen) & &
text十 (juu) & &
text九 (kyuu)
endarray
The missing hundred place is simply ignored.
Four digits are considered a group, unlike English, where three digits are a group. The group markers are:
beginarrayccc
10^4 & 10^8 & 10^12 & 10^16 \
text万 (man) & text億 (oku) & text兆 (choo) & text京 (kee)
endarray
For example, $1,2345,6789$ is read as 一億二千三百四十五万六千七百八十九 (ichioku nisensanbyakuyonjuugoman rokusennanahyakuhachijuukyuu). (The spaces are for ease of recognition only.) Note that 一 (ichi) is required before these group markers, unlike 十 (juu), 百 (hyaku), and 千 (sen).
0 is ゼロ (zero).
A negative integer $-n$ is read as マイナス (mainasu) followed by its absolute value $n$. For example, -5 is read as マイナス五 (mainasugo), because 5 is read as 五 (go).
When two syllables are joined, if the first syllable ends with "n" and the second starts with one of "aeiouy", then a separator ' is added between. For example, 1001 is 千一 (sen'ichi) and 1004 is 千四 (sen'yon).
c++ c++17 numbers-to-words
$endgroup$
Inspired by CtCI 16.8: Integer to English phrase in C++, I wrote a program to show the Japanese reading of an integer (positive, negative, or zero). The Japanese is written in Hepburn romanization to avoid encoding problems. Also, traditional Hepburn is used to avoid macrons.
Unlike English, Japanese has sound changes when two words come together. The details are given at the end of the question.
The program handles integers $n$ in the range $-2^63 le n < 2^63$.
Code
/**
* Integer to Japanese reading
*
* Japanese reading is written in Hepburn Roomaji. Traditional
* Hepburn is used to avoid the need of macrons.
*/
#include <cassert>
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
using number_t = std::int_fast64_t;
const std::vector<std::string> magnitudes =
"", "man", "oku", "choo", "kee",
;
const std::vector<std::string> thousands =
"", "sen", "nisen", "sanzen", "yonsen",
"gosen", "rokusen", "nanasen", "hassen", "kyuusen",
;
const std::vector<std::string> hundreds =
"", "hyaku", "nihyaku", "sanbyaku", "yonhyaku",
"gohyaku", "roppyaku", "nanahyaku", "happyaku", "kyuuhyaku",
;
const std::vector<std::string> tens =
"", "juu", "nijuu", "sanjuu", "yonjuu",
"gojuu", "rokujuu", "nanajuu", "hachijuu", "kyuujuu",
;
const std::vector<std::string> ones =
"", "ichi", "ni", "san", "yon",
"go", "roku", "nana", "hachi", "kyuu",
;
// returns 10000^n
constexpr number_t magnitude(std::size_t n)
number_t result = 1;
while (n--)
result *= 10000;
return result;
constexpr bool is_vowel(char c)
switch (c)
case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
return true;
default:
return false;
// joins two strings according to Japanese rules
void push(std::string& lhs, const std::string& rhs)
if (lhs.back() == 'n' && is_vowel(rhs.front()))
lhs += ''';
lhs += rhs;
// converts nonnegative numbers less than 10000
std::string group_name(number_t number)
assert(0 <= number && number < 10000);
std::string result = thousands[number / 1000];
number %= 1000;
push(result, hundreds[number / 100]);
number %= 100;
push(result, tens[number / 10]);
number %= 10;
push(result, ones[number]);
return result;
std::string to_Japanese(number_t number)
if (number == 0)
return "zero";
std::string result;
if (number < 0)
result = "mainasu";
number = -number;
number_t mag = magnitude(magnitudes.size() - 1);
for (std::size_t i = magnitudes.size(); i-- > 0; mag /= 10000)
if (auto group = number / mag; group > 0)
push(result, group_name(group));
push(result, magnitudes[i]);
number %= mag;
return result;
int main()
for (number_t number; std::cin >> number;)
std::cout << to_Japanese(number) << "n";
Example session
0
zero
1
ichi
2
ni
3
san
6789678967896789
rokusennanahyakuhachijuukyuuchoorokusennanahyakuhachijuukyuuokurokusennanahyakuhachijuukyuumanrokusennanahyakuhachijuukyuu
-1234567898765432
mainasusennihyakusanjuuyonchoogosenroppyakunanajuuhachiokukyuusenhappyakunanajuurokumangosen'yonhyakusanjuuni
Japanese numerals
(You can skip this part if you are familiar with Japanese.)
In the following table, red entries involve sound change.
beginarrayll
textNumber & textJapanese reading \
1 & text一 (ichi) \
2 & text二 (ni) \
3 & text三 (san) \
4 & text四 (yon) \
5 & text五 (go) \
6 & text六 (roku) \
7 & text七 (nana) \
8 & text八 (hachi) \
9 & text九 (kyuu) \
10 & text十 (juu) \
20 & text二十 (nijuu) \
30 & text三十 (sanjuu) \
40 & text四十 (yonjuu) \
50 & text五十 (gojuu) \
60 & text六十 (rokujuu) \
70 & text七十 (nanajuu) \
80 & text八十 (hachijuu) \
90 & text九十 (kyuujuu) \
100 & text百 (hyaku) \
200 & text二百 (nihyaku) \
300 & text三百 colorredtext(sanbyaku) \
400 & text四百 (yonhyaku) \
500 & text五百 (gohyaku) \
600 & text六百 colorredtext(roppyaku) \
700 & text七百 (nanahyaku) \
800 & text八百 colorredtext(happyaku) \
900 & text九百 (kyuuhyaku) \
1000 & text千 (sen) \
2000 & text二千 (nisen) \
3000 & text三千 colorredtext(sanzen) \
4000 & text四千 (yonsen) \
5000 & text五千 (gosen) \
6000 & text六千 (rokusen) \
7000 & text七千 (nanasen) \
8000 & text八千 colorredtext(hassen) \
9000 & text九千 (kyuusen) \
endarray
Larger numbers are considered the sums of smaller numbers. For example:
beginarrayccccccc
2019 & = & 2000 & + & 10 & + & 9 \
text二千十九 (nisenjuukyuu) & &
text二千 (nisen) & &
text十 (juu) & &
text九 (kyuu)
endarray
The missing hundred place is simply ignored.
Four digits are considered a group, unlike English, where three digits are a group. The group markers are:
beginarrayccc
10^4 & 10^8 & 10^12 & 10^16 \
text万 (man) & text億 (oku) & text兆 (choo) & text京 (kee)
endarray
For example, $1,2345,6789$ is read as 一億二千三百四十五万六千七百八十九 (ichioku nisensanbyakuyonjuugoman rokusennanahyakuhachijuukyuu). (The spaces are for ease of recognition only.) Note that 一 (ichi) is required before these group markers, unlike 十 (juu), 百 (hyaku), and 千 (sen).
0 is ゼロ (zero).
A negative integer $-n$ is read as マイナス (mainasu) followed by its absolute value $n$. For example, -5 is read as マイナス五 (mainasugo), because 5 is read as 五 (go).
When two syllables are joined, if the first syllable ends with "n" and the second starts with one of "aeiouy", then a separator ' is added between. For example, 1001 is 千一 (sen'ichi) and 1004 is 千四 (sen'yon).
c++ c++17 numbers-to-words
c++ c++17 numbers-to-words
edited Jul 28 at 11:53
L. F.
asked Jul 28 at 11:44
L. F.L. F.
3,7471 gold badge7 silver badges37 bronze badges
3,7471 gold badge7 silver badges37 bronze badges
add a comment
|
add a comment
|
5 Answers
5
active
oldest
votes
$begingroup$
The push
function may invoke undefined behavior. When you create a new std::string
, I don't think it is guaranteed to be null-terminated since that would incur a runtime cost for no benefit other than C compatibility. Only after calling c_str()
the terminating null character is there. Because the string is really empty, calling back()
accesses an out-of-bounds element.
You claim that your code works for $-2^63$ but you didn't add that number as a test case. I would expect it to not work since -(-2**63)
is still negative.
Besides these two issues, your code reads well and is easy to understand. Adding the additional documentation was a very good idea for everyone not fluent in Japanese.
$endgroup$
$begingroup$
I see. The problem is thatback
accesses the nonexistent element. (The terminating null character doesn't change that.)
$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires thatoperator[]
withpos=size()
references the terminating0
. What makesback()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when.empty() == true
. And moreover that it's equivalent tooperator[](size() - 1)
which would wrap the unsigned position.
$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,operator[](size() - 1)
only applies ifempty()
is false, so wrapping is irrelevant I guess.
$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practiceg++ -O0
with libstdc++ (on Arch Linux) gives0
when doing.back()
on an emptystd::string
, so it doesn't help you detect this bug by crashing on that UB.
$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so.data()
and.c_str()
can be a no-op that just returns one of the class member vars.
$endgroup$
– Peter Cordes
Jul 29 at 6:36
|
show 1 more comment
$begingroup$
Your magnitudes should be chou
and kei
(as in the supercomputer, as an aside). Also, to_Japanese()
would be better named to_romaji()
. As an exercise, you could try to_Japanese(number, KANJI|HIRAGANA|ROMAJI)
also.
Furthermore, it's icchou
, not ichichou
, and ikkei
, not ichikei
.
$endgroup$
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, andchoo
is correct, although I always usechou
as it's IME-friendly, but thensennana
would be typedsennnana
. We're now straying into Japanese Language territory...
$endgroup$
– Ken Y-N
Jul 29 at 5:59
add a comment
|
$begingroup$
I think it would be better to generate the 漢字 versions of the numbers, as it's more useful in general. Make a separate class responsible for romanization (or phonetic conversion in general so it can support kana).
Using kanji also allows for somewhat trivially adding support for formal numbers (大字), which is kind of cool/useful.
I would also recommend adding support for breaking up the romaji sequences as reading very large numbers in romaji with no spaces is not at all fun. It could be an optional flag. A natural place to add spaces would be between magnitudes at least, or maybe between all of the various groupings you've already put together (ones, tens, hundreds, etc.).
As for using romaji to avoid encoding issues, I recommending biting the bullet and learning how to support Unicode correctly as it will be extremely useful.
$endgroup$
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
add a comment
|
$begingroup$
I know in that in English that each word would be separate where the program is printing the all of the numbers merged together. Is this the actual functionality in Japanese?
Since the code might be useful in many places it might be better of the translation code as in a class.
Use of Vertical Space
Generally code is easier to read and maintain when only one value is on a line. This would apply to the initialization of the vectors and the switch statement in the function is_vowel()
. For maintenance reasons it is much easier to insert a line where it needs to be than it is to add a value to a comma separated list.
is_vowel function
There would be less code if the vowels were in a std::map rather than a switch statement. Here are discussions on stack overflow and software engineering.
This portion of the answer has been modified to remove the statement that there might be a performance improvement using std::map. If map used a simple index into an array that might be true, however it is not a simple index into an array.
Assert
Assert statements are generally used for debugging purposes and terminate the program. Assert statements may be removed when the code is compiled without debugging as well. I don't expect to see asserts in production level code because it implies that the code is not yet debugged.
$endgroup$
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
$begingroup$
^ Agreed with Tomas. Provide proof.std::map
is dynamically-allocated, node-based, and definitely not cache friendly
$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
$begingroup$
Failedassert()
s do not throw - they terminate the program.
$endgroup$
– Toby Speight
Jul 29 at 11:14
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.if
statement + error -> recoverable error, can be usually handled by a human.
$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
|
show 10 more comments
$begingroup$
You use of std::vector<std::string>
for the arrays of string constants is wasteful. Both std::vector
and std::string
are dynamic types that can potentially allocate. A much more lightweight choice would be constexpr std::array<const char*>
or constexpr std::array<std::string_view>
.
$endgroup$
$begingroup$
Fair point.string
is probably not dynamic in this case due to SSO, butvector
is quite wasteful.
$endgroup$
– L. F.
Jul 29 at 10:42
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to usestd::string_view
orconst char*
. The compiler will also very likely be able to optimize better.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225082%2fjapanese-reading-of-an-integer%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
The push
function may invoke undefined behavior. When you create a new std::string
, I don't think it is guaranteed to be null-terminated since that would incur a runtime cost for no benefit other than C compatibility. Only after calling c_str()
the terminating null character is there. Because the string is really empty, calling back()
accesses an out-of-bounds element.
You claim that your code works for $-2^63$ but you didn't add that number as a test case. I would expect it to not work since -(-2**63)
is still negative.
Besides these two issues, your code reads well and is easy to understand. Adding the additional documentation was a very good idea for everyone not fluent in Japanese.
$endgroup$
$begingroup$
I see. The problem is thatback
accesses the nonexistent element. (The terminating null character doesn't change that.)
$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires thatoperator[]
withpos=size()
references the terminating0
. What makesback()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when.empty() == true
. And moreover that it's equivalent tooperator[](size() - 1)
which would wrap the unsigned position.
$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,operator[](size() - 1)
only applies ifempty()
is false, so wrapping is irrelevant I guess.
$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practiceg++ -O0
with libstdc++ (on Arch Linux) gives0
when doing.back()
on an emptystd::string
, so it doesn't help you detect this bug by crashing on that UB.
$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so.data()
and.c_str()
can be a no-op that just returns one of the class member vars.
$endgroup$
– Peter Cordes
Jul 29 at 6:36
|
show 1 more comment
$begingroup$
The push
function may invoke undefined behavior. When you create a new std::string
, I don't think it is guaranteed to be null-terminated since that would incur a runtime cost for no benefit other than C compatibility. Only after calling c_str()
the terminating null character is there. Because the string is really empty, calling back()
accesses an out-of-bounds element.
You claim that your code works for $-2^63$ but you didn't add that number as a test case. I would expect it to not work since -(-2**63)
is still negative.
Besides these two issues, your code reads well and is easy to understand. Adding the additional documentation was a very good idea for everyone not fluent in Japanese.
$endgroup$
$begingroup$
I see. The problem is thatback
accesses the nonexistent element. (The terminating null character doesn't change that.)
$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires thatoperator[]
withpos=size()
references the terminating0
. What makesback()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when.empty() == true
. And moreover that it's equivalent tooperator[](size() - 1)
which would wrap the unsigned position.
$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,operator[](size() - 1)
only applies ifempty()
is false, so wrapping is irrelevant I guess.
$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practiceg++ -O0
with libstdc++ (on Arch Linux) gives0
when doing.back()
on an emptystd::string
, so it doesn't help you detect this bug by crashing on that UB.
$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so.data()
and.c_str()
can be a no-op that just returns one of the class member vars.
$endgroup$
– Peter Cordes
Jul 29 at 6:36
|
show 1 more comment
$begingroup$
The push
function may invoke undefined behavior. When you create a new std::string
, I don't think it is guaranteed to be null-terminated since that would incur a runtime cost for no benefit other than C compatibility. Only after calling c_str()
the terminating null character is there. Because the string is really empty, calling back()
accesses an out-of-bounds element.
You claim that your code works for $-2^63$ but you didn't add that number as a test case. I would expect it to not work since -(-2**63)
is still negative.
Besides these two issues, your code reads well and is easy to understand. Adding the additional documentation was a very good idea for everyone not fluent in Japanese.
$endgroup$
The push
function may invoke undefined behavior. When you create a new std::string
, I don't think it is guaranteed to be null-terminated since that would incur a runtime cost for no benefit other than C compatibility. Only after calling c_str()
the terminating null character is there. Because the string is really empty, calling back()
accesses an out-of-bounds element.
You claim that your code works for $-2^63$ but you didn't add that number as a test case. I would expect it to not work since -(-2**63)
is still negative.
Besides these two issues, your code reads well and is easy to understand. Adding the additional documentation was a very good idea for everyone not fluent in Japanese.
edited Jul 29 at 5:22
answered Jul 29 at 5:17
Roland IlligRoland Illig
15.9k2 gold badges24 silver badges59 bronze badges
15.9k2 gold badges24 silver badges59 bronze badges
$begingroup$
I see. The problem is thatback
accesses the nonexistent element. (The terminating null character doesn't change that.)
$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires thatoperator[]
withpos=size()
references the terminating0
. What makesback()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when.empty() == true
. And moreover that it's equivalent tooperator[](size() - 1)
which would wrap the unsigned position.
$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,operator[](size() - 1)
only applies ifempty()
is false, so wrapping is irrelevant I guess.
$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practiceg++ -O0
with libstdc++ (on Arch Linux) gives0
when doing.back()
on an emptystd::string
, so it doesn't help you detect this bug by crashing on that UB.
$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so.data()
and.c_str()
can be a no-op that just returns one of the class member vars.
$endgroup$
– Peter Cordes
Jul 29 at 6:36
|
show 1 more comment
$begingroup$
I see. The problem is thatback
accesses the nonexistent element. (The terminating null character doesn't change that.)
$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires thatoperator[]
withpos=size()
references the terminating0
. What makesback()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when.empty() == true
. And moreover that it's equivalent tooperator[](size() - 1)
which would wrap the unsigned position.
$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,operator[](size() - 1)
only applies ifempty()
is false, so wrapping is irrelevant I guess.
$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practiceg++ -O0
with libstdc++ (on Arch Linux) gives0
when doing.back()
on an emptystd::string
, so it doesn't help you detect this bug by crashing on that UB.
$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so.data()
and.c_str()
can be a no-op that just returns one of the class member vars.
$endgroup$
– Peter Cordes
Jul 29 at 6:36
$begingroup$
I see. The problem is that
back
accesses the nonexistent element. (The terminating null character doesn't change that.)$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
I see. The problem is that
back
accesses the nonexistent element. (The terminating null character doesn't change that.)$endgroup$
– L. F.
Jul 29 at 5:22
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires that
operator[]
with pos=size()
references the terminating 0
. What makes back()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when .empty() == true
. And moreover that it's equivalent to operator[](size() - 1)
which would wrap the unsigned position.$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
@L.F. Yes, in reality most std::string implementations will have a terminating 0 byte at all times. And in fact C++11 and later requires that
operator[]
with pos=size()
references the terminating 0
. What makes back()
UB is that en.cppreference.com/w/cpp/string/basic_string/back says it's UB when .empty() == true
. And moreover that it's equivalent to operator[](size() - 1)
which would wrap the unsigned position.$endgroup$
– Peter Cordes
Jul 29 at 6:28
$begingroup$
The code definitely needs a check. Also,
operator[](size() - 1)
only applies if empty()
is false, so wrapping is irrelevant I guess.$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
The code definitely needs a check. Also,
operator[](size() - 1)
only applies if empty()
is false, so wrapping is irrelevant I guess.$endgroup$
– L. F.
Jul 29 at 6:31
$begingroup$
In practice
g++ -O0
with libstdc++ (on Arch Linux) gives 0
when doing .back()
on an empty std::string
, so it doesn't help you detect this bug by crashing on that UB.$endgroup$
– Peter Cordes
Jul 29 at 6:31
$begingroup$
In practice
g++ -O0
with libstdc++ (on Arch Linux) gives 0
when doing .back()
on an empty std::string
, so it doesn't help you detect this bug by crashing on that UB.$endgroup$
– Peter Cordes
Jul 29 at 6:31
3
3
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With
.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so .data()
and .c_str()
can be a no-op that just returns one of the class member vars.$endgroup$
– Peter Cordes
Jul 29 at 6:36
$begingroup$
@L.F.: fun facts: Legality of COW std::string implementation in C++11 shows how some of the new requirements in C++11 basically make efficient COW implementation of std::string impossible. With
.data()
also requiring a 0-terminated string, the obvious/intended implementation is to always maintain that so .data()
and .c_str()
can be a no-op that just returns one of the class member vars.$endgroup$
– Peter Cordes
Jul 29 at 6:36
|
show 1 more comment
$begingroup$
Your magnitudes should be chou
and kei
(as in the supercomputer, as an aside). Also, to_Japanese()
would be better named to_romaji()
. As an exercise, you could try to_Japanese(number, KANJI|HIRAGANA|ROMAJI)
also.
Furthermore, it's icchou
, not ichichou
, and ikkei
, not ichikei
.
$endgroup$
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, andchoo
is correct, although I always usechou
as it's IME-friendly, but thensennana
would be typedsennnana
. We're now straying into Japanese Language territory...
$endgroup$
– Ken Y-N
Jul 29 at 5:59
add a comment
|
$begingroup$
Your magnitudes should be chou
and kei
(as in the supercomputer, as an aside). Also, to_Japanese()
would be better named to_romaji()
. As an exercise, you could try to_Japanese(number, KANJI|HIRAGANA|ROMAJI)
also.
Furthermore, it's icchou
, not ichichou
, and ikkei
, not ichikei
.
$endgroup$
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, andchoo
is correct, although I always usechou
as it's IME-friendly, but thensennana
would be typedsennnana
. We're now straying into Japanese Language territory...
$endgroup$
– Ken Y-N
Jul 29 at 5:59
add a comment
|
$begingroup$
Your magnitudes should be chou
and kei
(as in the supercomputer, as an aside). Also, to_Japanese()
would be better named to_romaji()
. As an exercise, you could try to_Japanese(number, KANJI|HIRAGANA|ROMAJI)
also.
Furthermore, it's icchou
, not ichichou
, and ikkei
, not ichikei
.
$endgroup$
Your magnitudes should be chou
and kei
(as in the supercomputer, as an aside). Also, to_Japanese()
would be better named to_romaji()
. As an exercise, you could try to_Japanese(number, KANJI|HIRAGANA|ROMAJI)
also.
Furthermore, it's icchou
, not ichichou
, and ikkei
, not ichikei
.
answered Jul 29 at 0:46
Ken Y-NKen Y-N
2591 silver badge4 bronze badges
2591 silver badge4 bronze badges
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, andchoo
is correct, although I always usechou
as it's IME-friendly, but thensennana
would be typedsennnana
. We're now straying into Japanese Language territory...
$endgroup$
– Ken Y-N
Jul 29 at 5:59
add a comment
|
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, andchoo
is correct, although I always usechou
as it's IME-friendly, but thensennana
would be typedsennnana
. We're now straying into Japanese Language territory...
$endgroup$
– Ken Y-N
Jul 29 at 5:59
1
1
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
$begingroup$
Thank you for correcting my Japanese! I am a beginner and sorry for the mistakes. Regarding chou vs choo: what I learned is that when おう is a long "o", it is written as "oo" instead of "ou". I figured out that different romaji systems differ on this. And "ichichou" is so silly ;)
$endgroup$
– L. F.
Jul 29 at 0:50
2
2
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, and
choo
is correct, although I always use chou
as it's IME-friendly, but then sennana
would be typed sennnana
. We're now straying into Japanese Language territory...$endgroup$
– Ken Y-N
Jul 29 at 5:59
$begingroup$
Yes, there's lots of different romaji versions - I looked up the most common Hepburn, and
choo
is correct, although I always use chou
as it's IME-friendly, but then sennana
would be typed sennnana
. We're now straying into Japanese Language territory...$endgroup$
– Ken Y-N
Jul 29 at 5:59
add a comment
|
$begingroup$
I think it would be better to generate the 漢字 versions of the numbers, as it's more useful in general. Make a separate class responsible for romanization (or phonetic conversion in general so it can support kana).
Using kanji also allows for somewhat trivially adding support for formal numbers (大字), which is kind of cool/useful.
I would also recommend adding support for breaking up the romaji sequences as reading very large numbers in romaji with no spaces is not at all fun. It could be an optional flag. A natural place to add spaces would be between magnitudes at least, or maybe between all of the various groupings you've already put together (ones, tens, hundreds, etc.).
As for using romaji to avoid encoding issues, I recommending biting the bullet and learning how to support Unicode correctly as it will be extremely useful.
$endgroup$
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
add a comment
|
$begingroup$
I think it would be better to generate the 漢字 versions of the numbers, as it's more useful in general. Make a separate class responsible for romanization (or phonetic conversion in general so it can support kana).
Using kanji also allows for somewhat trivially adding support for formal numbers (大字), which is kind of cool/useful.
I would also recommend adding support for breaking up the romaji sequences as reading very large numbers in romaji with no spaces is not at all fun. It could be an optional flag. A natural place to add spaces would be between magnitudes at least, or maybe between all of the various groupings you've already put together (ones, tens, hundreds, etc.).
As for using romaji to avoid encoding issues, I recommending biting the bullet and learning how to support Unicode correctly as it will be extremely useful.
$endgroup$
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
add a comment
|
$begingroup$
I think it would be better to generate the 漢字 versions of the numbers, as it's more useful in general. Make a separate class responsible for romanization (or phonetic conversion in general so it can support kana).
Using kanji also allows for somewhat trivially adding support for formal numbers (大字), which is kind of cool/useful.
I would also recommend adding support for breaking up the romaji sequences as reading very large numbers in romaji with no spaces is not at all fun. It could be an optional flag. A natural place to add spaces would be between magnitudes at least, or maybe between all of the various groupings you've already put together (ones, tens, hundreds, etc.).
As for using romaji to avoid encoding issues, I recommending biting the bullet and learning how to support Unicode correctly as it will be extremely useful.
$endgroup$
I think it would be better to generate the 漢字 versions of the numbers, as it's more useful in general. Make a separate class responsible for romanization (or phonetic conversion in general so it can support kana).
Using kanji also allows for somewhat trivially adding support for formal numbers (大字), which is kind of cool/useful.
I would also recommend adding support for breaking up the romaji sequences as reading very large numbers in romaji with no spaces is not at all fun. It could be an optional flag. A natural place to add spaces would be between magnitudes at least, or maybe between all of the various groupings you've already put together (ones, tens, hundreds, etc.).
As for using romaji to avoid encoding issues, I recommending biting the bullet and learning how to support Unicode correctly as it will be extremely useful.
answered Jul 29 at 3:12
briantistbriantist
1,4799 silver badges9 bronze badges
1,4799 silver badges9 bronze badges
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
add a comment
|
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
1
1
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
$begingroup$
Insightful. Although romanization is nontrivial AFAIK since one kanji can have multiple readings ... Spaces in between romaji is also a good idea.
$endgroup$
– L. F.
Jul 29 at 3:25
1
1
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
$begingroup$
@L.F. romanization doesn't have to support the entirety of Japanese, as this code is number focused, and you've already decided on the readings for each of the kanji involved anyway (or rather; there's only one right answer for these in this context); and that means katakana and hiragana phonetic readings are just as easy at that point.
$endgroup$
– briantist
Jul 29 at 3:30
add a comment
|
$begingroup$
I know in that in English that each word would be separate where the program is printing the all of the numbers merged together. Is this the actual functionality in Japanese?
Since the code might be useful in many places it might be better of the translation code as in a class.
Use of Vertical Space
Generally code is easier to read and maintain when only one value is on a line. This would apply to the initialization of the vectors and the switch statement in the function is_vowel()
. For maintenance reasons it is much easier to insert a line where it needs to be than it is to add a value to a comma separated list.
is_vowel function
There would be less code if the vowels were in a std::map rather than a switch statement. Here are discussions on stack overflow and software engineering.
This portion of the answer has been modified to remove the statement that there might be a performance improvement using std::map. If map used a simple index into an array that might be true, however it is not a simple index into an array.
Assert
Assert statements are generally used for debugging purposes and terminate the program. Assert statements may be removed when the code is compiled without debugging as well. I don't expect to see asserts in production level code because it implies that the code is not yet debugged.
$endgroup$
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
$begingroup$
^ Agreed with Tomas. Provide proof.std::map
is dynamically-allocated, node-based, and definitely not cache friendly
$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
$begingroup$
Failedassert()
s do not throw - they terminate the program.
$endgroup$
– Toby Speight
Jul 29 at 11:14
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.if
statement + error -> recoverable error, can be usually handled by a human.
$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
|
show 10 more comments
$begingroup$
I know in that in English that each word would be separate where the program is printing the all of the numbers merged together. Is this the actual functionality in Japanese?
Since the code might be useful in many places it might be better of the translation code as in a class.
Use of Vertical Space
Generally code is easier to read and maintain when only one value is on a line. This would apply to the initialization of the vectors and the switch statement in the function is_vowel()
. For maintenance reasons it is much easier to insert a line where it needs to be than it is to add a value to a comma separated list.
is_vowel function
There would be less code if the vowels were in a std::map rather than a switch statement. Here are discussions on stack overflow and software engineering.
This portion of the answer has been modified to remove the statement that there might be a performance improvement using std::map. If map used a simple index into an array that might be true, however it is not a simple index into an array.
Assert
Assert statements are generally used for debugging purposes and terminate the program. Assert statements may be removed when the code is compiled without debugging as well. I don't expect to see asserts in production level code because it implies that the code is not yet debugged.
$endgroup$
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
$begingroup$
^ Agreed with Tomas. Provide proof.std::map
is dynamically-allocated, node-based, and definitely not cache friendly
$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
$begingroup$
Failedassert()
s do not throw - they terminate the program.
$endgroup$
– Toby Speight
Jul 29 at 11:14
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.if
statement + error -> recoverable error, can be usually handled by a human.
$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
|
show 10 more comments
$begingroup$
I know in that in English that each word would be separate where the program is printing the all of the numbers merged together. Is this the actual functionality in Japanese?
Since the code might be useful in many places it might be better of the translation code as in a class.
Use of Vertical Space
Generally code is easier to read and maintain when only one value is on a line. This would apply to the initialization of the vectors and the switch statement in the function is_vowel()
. For maintenance reasons it is much easier to insert a line where it needs to be than it is to add a value to a comma separated list.
is_vowel function
There would be less code if the vowels were in a std::map rather than a switch statement. Here are discussions on stack overflow and software engineering.
This portion of the answer has been modified to remove the statement that there might be a performance improvement using std::map. If map used a simple index into an array that might be true, however it is not a simple index into an array.
Assert
Assert statements are generally used for debugging purposes and terminate the program. Assert statements may be removed when the code is compiled without debugging as well. I don't expect to see asserts in production level code because it implies that the code is not yet debugged.
$endgroup$
I know in that in English that each word would be separate where the program is printing the all of the numbers merged together. Is this the actual functionality in Japanese?
Since the code might be useful in many places it might be better of the translation code as in a class.
Use of Vertical Space
Generally code is easier to read and maintain when only one value is on a line. This would apply to the initialization of the vectors and the switch statement in the function is_vowel()
. For maintenance reasons it is much easier to insert a line where it needs to be than it is to add a value to a comma separated list.
is_vowel function
There would be less code if the vowels were in a std::map rather than a switch statement. Here are discussions on stack overflow and software engineering.
This portion of the answer has been modified to remove the statement that there might be a performance improvement using std::map. If map used a simple index into an array that might be true, however it is not a simple index into an array.
Assert
Assert statements are generally used for debugging purposes and terminate the program. Assert statements may be removed when the code is compiled without debugging as well. I don't expect to see asserts in production level code because it implies that the code is not yet debugged.
edited Jul 30 at 18:24
answered Jul 28 at 12:59
pacmaninbwpacmaninbw
8,9212 gold badges22 silver badges46 bronze badges
8,9212 gold badges22 silver badges46 bronze badges
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
$begingroup$
^ Agreed with Tomas. Provide proof.std::map
is dynamically-allocated, node-based, and definitely not cache friendly
$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
$begingroup$
Failedassert()
s do not throw - they terminate the program.
$endgroup$
– Toby Speight
Jul 29 at 11:14
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.if
statement + error -> recoverable error, can be usually handled by a human.
$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
|
show 10 more comments
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
$begingroup$
^ Agreed with Tomas. Provide proof.std::map
is dynamically-allocated, node-based, and definitely not cache friendly
$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
$begingroup$
Failedassert()
s do not throw - they terminate the program.
$endgroup$
– Toby Speight
Jul 29 at 11:14
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.if
statement + error -> recoverable error, can be usually handled by a human.
$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
12
12
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
$begingroup$
"There would be less code and the performance might be better if the vowels were in a std::map rather than a switch statement." - do you have anything to support a claim that std::map is faster than a raw switch statement? Because I very much doubt that.
$endgroup$
– Tomáš Zato
Jul 29 at 9:26
5
5
$begingroup$
^ Agreed with Tomas. Provide proof.
std::map
is dynamically-allocated, node-based, and definitely not cache friendly$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
$begingroup$
^ Agreed with Tomas. Provide proof.
std::map
is dynamically-allocated, node-based, and definitely not cache friendly$endgroup$
– Vittorio Romeo
Jul 29 at 10:41
10
10
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
$begingroup$
"Assert statements are generally used for debugging purposes and throw an exception." - NO. Assert statements exist to test preconditions. Exceptions have nothing to do with preconditions. This answer is harmful.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:42
7
7
$begingroup$
Failed
assert()
s do not throw - they terminate the program.$endgroup$
– Toby Speight
Jul 29 at 11:14
$begingroup$
Failed
assert()
s do not throw - they terminate the program.$endgroup$
– Toby Speight
Jul 29 at 11:14
6
6
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.
if
statement + error -> recoverable error, can be usually handled by a human.$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
$begingroup$
"It is generally better to use if statements that provide error messages rather than assert statements." - This is still severely wrong and harmful. They have completely different use cases. Assert -> precondition check, contract breakage, unrecoverable error.
if
statement + error -> recoverable error, can be usually handled by a human.$endgroup$
– Vittorio Romeo
Jul 29 at 13:15
|
show 10 more comments
$begingroup$
You use of std::vector<std::string>
for the arrays of string constants is wasteful. Both std::vector
and std::string
are dynamic types that can potentially allocate. A much more lightweight choice would be constexpr std::array<const char*>
or constexpr std::array<std::string_view>
.
$endgroup$
$begingroup$
Fair point.string
is probably not dynamic in this case due to SSO, butvector
is quite wasteful.
$endgroup$
– L. F.
Jul 29 at 10:42
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to usestd::string_view
orconst char*
. The compiler will also very likely be able to optimize better.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
add a comment
|
$begingroup$
You use of std::vector<std::string>
for the arrays of string constants is wasteful. Both std::vector
and std::string
are dynamic types that can potentially allocate. A much more lightweight choice would be constexpr std::array<const char*>
or constexpr std::array<std::string_view>
.
$endgroup$
$begingroup$
Fair point.string
is probably not dynamic in this case due to SSO, butvector
is quite wasteful.
$endgroup$
– L. F.
Jul 29 at 10:42
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to usestd::string_view
orconst char*
. The compiler will also very likely be able to optimize better.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
add a comment
|
$begingroup$
You use of std::vector<std::string>
for the arrays of string constants is wasteful. Both std::vector
and std::string
are dynamic types that can potentially allocate. A much more lightweight choice would be constexpr std::array<const char*>
or constexpr std::array<std::string_view>
.
$endgroup$
You use of std::vector<std::string>
for the arrays of string constants is wasteful. Both std::vector
and std::string
are dynamic types that can potentially allocate. A much more lightweight choice would be constexpr std::array<const char*>
or constexpr std::array<std::string_view>
.
answered Jul 29 at 10:40
Vittorio RomeoVittorio Romeo
3051 gold badge5 silver badges21 bronze badges
3051 gold badge5 silver badges21 bronze badges
$begingroup$
Fair point.string
is probably not dynamic in this case due to SSO, butvector
is quite wasteful.
$endgroup$
– L. F.
Jul 29 at 10:42
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to usestd::string_view
orconst char*
. The compiler will also very likely be able to optimize better.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
add a comment
|
$begingroup$
Fair point.string
is probably not dynamic in this case due to SSO, butvector
is quite wasteful.
$endgroup$
– L. F.
Jul 29 at 10:42
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to usestd::string_view
orconst char*
. The compiler will also very likely be able to optimize better.
$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
$begingroup$
Fair point.
string
is probably not dynamic in this case due to SSO, but vector
is quite wasteful.$endgroup$
– L. F.
Jul 29 at 10:42
$begingroup$
Fair point.
string
is probably not dynamic in this case due to SSO, but vector
is quite wasteful.$endgroup$
– L. F.
Jul 29 at 10:42
1
1
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to use
std::string_view
or const char*
. The compiler will also very likely be able to optimize better.$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
$begingroup$
Still, I like using the most minimal tool for the job whenever possible. Even if the constants are going to fit in SSO, it's good practice to use
std::string_view
or const char*
. The compiler will also very likely be able to optimize better.$endgroup$
– Vittorio Romeo
Jul 29 at 10:44
add a comment
|
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225082%2fjapanese-reading-of-an-integer%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown