Article View: comp.lang.java.programmer
Article #633Re: i18n and numbers
From: Erik Peterson
Date: Wed, 24 May 2000 00:00
Date: Wed, 24 May 2000 00:00
272 lines
9157 bytes
9157 bytes
> The following test program does not convert numbers into correct chinse
> numbers,
> but still shows the 1,2,3,4 etc number. Should it not have been the
> chinse
> charaters for the numbers? Or this there another way around?
Western numbers work just as well in Chinese as the native
ones using characters do, especially for math and finance. Maybe
JavaSoft just decided to go with 1, 2, 3 instead of yi1, er4, san1
Here's some Java code that will do the conversion. May still need
some debugging but works.
Also see http://www.mandarintools.com/numbers.html
import java.lang.*;
import java.util.*;
class numbers {
public final static String minus = "\u8ca0";
public final static String sminus = "\u8d1f";
public final static String[] digits = {"\u96f6", "\u4e00", "\u4e8c", "\u4e09", "\u56db", "\u4e94", "\u516d", "\u4e03", "\u516b", "\u4e5d"};
public final static String[] beforeWan = {"\u5341", "\u767e", "\u5343"};
public final static String[] sbeforeWan = {"\u5341", "\u767e", "\u5343"};
public final static String[] afterWan = {"", "\u842c", "\u5104", "\u5146"};
public final static String[] safterWan = {"", "\u4e07", "\u4ebf", "\u5146"};
public final static String ALTTWO = "\u5169";
public final static long TEN = 10;
public numbers() {
}
public static String EnglishToChineseNumber(long enumber) {
int[] powers = new int[30];
int power = 0;
int value = 0;
boolean negative = false, // is it a negative integer
inzero = false, // are we in a stretch or 1 or more zeros (only add one zero for the stretch)
canaddzero = false; // only add a zero if there's something non-zero on both sides of it
StringBuffer cnumber = new StringBuffer();
// If zero, just return zero
if (enumber == 0) {
return digits[0];
}
// Check if it's negative, set the negative flag and make it positive
if (enumber < 0) {
negative = true;
enumber = -enumber;
}
// Get the value of the coefficient for each power of ten
while (Math.pow(TEN, power) <= enumber) {
value = (int)((enumber % Math.pow(TEN, power+1))/Math.pow(TEN, power));
powers[power] = value;
// Subtract out the current power's coefficient and increase the power
enumber -= enumber % Math.pow(TEN, power+1);
power++;
}
// Take the decomposition of the number from above and generate the Chinese equivalent
for (int i = 0; i < power; i++) {
//System.out.println("10^" + i + ":\t" + powers[i]);
if ((i % 4) == 0) { // Reached the next four powers up level
if (powers[i] != 0) {
inzero = false;
canaddzero = true;
cnumber.insert(0, digits[powers[i]] + afterWan[i/4]);
} else {
// Check that something in the next three powers is non-zero before adding
if (((i+3 < power) && powers[i+3] != 0) ||
((i+2 < power) && powers[i+2] != 0) ||
((i+1 < power) && powers[i+1] != 0))
{
cnumber.insert(0, afterWan[i/4]);
}
}
} else { // Add one, tens, hundreds, or thousands place for each level
if (powers[i] != 0) {
inzero = false;
canaddzero = true;
if (power == 2 && i == 1 && powers[i] == 1) { // No \u4e00 with 10 through 19
cnumber.insert(0, beforeWan[(i%4)-1]);
//} else if ((i%4 = 3) && powers[i] == 2) { // when to use liang3 vs. er4
//cnumber.insert(0, ALTTWO + beforeWan[(i%4)-1]);
} else {
cnumber.insert(0, digits[powers[i]] + beforeWan[(i%4)-1]);
}
} else {
if (canaddzero == true && inzero == false) { // Only insert one \u96f6 for all consecutive zeroes
inzero = true;
cnumber.insert(0, digits[powers[i]]);
}
}
}
}
// Add the negative character
if (negative == true) {
cnumber.insert(0, minus);
}
return cnumber.toString();
}
public static int ChineseToEnglishNumber(String cnumber) {
int i;
boolean alldigits = true;
if (cnumber.length() > 1) {
for (i = 0; i < cnumber.length(); i++) {
if (cnumber.charAt(i) != '\u96f6' &&
cnumber.charAt(i) != '\u4e00' &&
cnumber.charAt(i) != '\u4e8c' &&
cnumber.charAt(i) != '\u4e09' &&
cnumber.charAt(i) != '\u56db' &&
cnumber.charAt(i) != '\u4e94' &&
cnumber.charAt(i) != '\u516d' &&
cnumber.charAt(i) != '\u4e03' &&
cnumber.charAt(i) != '\u516b' &&
cnumber.charAt(i) != '\u4e5d') {
alldigits = false;
}
}
if (alldigits == true) {
return ChineseToEnglishBrief(cnumber);
} else {
return ChineseToEnglishFull(cnumber);
}
} else {
return ChineseToEnglishFull(cnumber);
}
}
public static int ChineseToEnglishBrief(String cnumber) {
int place, digitval, total = 0;
for (place = 0; place < cnumber.length(); place++) {
for (digitval = 0; digitval < 10; digitval++) {
if (cnumber.charAt(place) == digits[digitval].charAt(0)) {
break;
}
}
total += digitval * Math.pow(10, cnumber.length() - 1 - place);
}
return total;
}
public static int ChineseToEnglishFull(String cnumber) {
boolean negative = false;
int cnumlength = cnumber.length();
int i, j, digitval, power = 0;
int leveltotal = 0;
int total = 0;
for (i = 0; i < cnumlength; i++) {
if (i == 0 && (cnumber.charAt(i) == '\u8d1f' ||
cnumber.charAt(i) == '\u8ca0')) {
negative = true;
} else if (i == 0 && cnumber.charAt(i) == '\u7b2c') {
// Do nothing for now
} else if (cnumber.charAt(i) == '\u5146') {
power = 12;
total += leveltotal * Math.pow(10,power);
leveltotal = 0;
power -= 4;
} else if (cnumber.charAt(i) == '\u5104' ||
cnumber.charAt(i) == '\u4ebf') {
power = 8;
total += leveltotal * Math.pow(10, power);
leveltotal = 0;
power -= 4;
} else if (cnumber.charAt(i) == '\u842c' ||
cnumber.charAt(i) == '\u4e07') {
power = 4;
total += leveltotal * Math.pow(10, power);
leveltotal = 0;
power -= 4;
} else if (cnumber.charAt(i) == '\u5343' ||
cnumber.charAt(i) == '\u4edf') {
leveltotal += 1000;
} else if (cnumber.charAt(i) == '\u767e' ||
cnumber.charAt(i) == '\u4f70') {
leveltotal += 100;
} else if (cnumber.charAt(i) == '\u5341' ||
cnumber.charAt(i) == '\u4ec0') {
leveltotal += 10;
} else if (cnumber.charAt(i) == '\u96f6' ||
cnumber.charAt(i) == '\u4e00' ||
cnumber.charAt(i) == '\u4e8c' ||
cnumber.charAt(i) == '\u4e09' ||
cnumber.charAt(i) == '\u56db' ||
cnumber.charAt(i) == '\u4e94' ||
cnumber.charAt(i) == '\u516d' ||
cnumber.charAt(i) == '\u4e03' ||
cnumber.charAt(i) == '\u516b' ||
cnumber.charAt(i) == '\u4e5d') {
for (digitval = 0; digitval < 10; digitval++) {
if (cnumber.charAt(i) == digits[digitval].charAt(0)) {
break;
}
}
if (i+1 < cnumlength &&
(cnumber.charAt(i+1) == '\u5341' || cnumber.charAt(i+1) == '\u4ec0')) {
leveltotal += digitval * 10;
i++;
} else if (i+1 < cnumlength &&
(cnumber.charAt(i+1) == '\u767e' || cnumber.charAt(i+1) == '\u4f70')) {
leveltotal += digitval * 100;
i++;
} else if (i+1 < cnumlength &&
(cnumber.charAt(i+1) == '\u5343' || cnumber.charAt(i+1) == '\u4edf')) {
leveltotal += digitval * 1000;
i++;
} else {
leveltotal += digitval;
}
} else {
// return negative infinity;
}
}
// Catch remaining leveltotal
//System.out.println("Level total " + leveltotal + " power " + power + " ten to power " + (10^power)/10);
total += leveltotal * Math.pow(10, power);
if (negative == true) { total = -total; }
return total;
}
public static void main(String[] argc) {
long enumber;
if (argc.length == 0) {
enumber = -10309300932L;
} else {
enumber = Integer.parseInt(argc[0]);
}
System.out.println(EnglishToChineseNumber(enumber));
System.out.println(ChineseToEnglishNumber("\u4e8c\u5341\u4e5d"));
System.out.println(ChineseToEnglishNumber("\u4e00\u4e5d\u4e5d\u4e5d"));
}
}
Technical Details
Message-ID:
<392C0D3C.AEA53AC5@erols.com>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<392B9315.B5D7CF66@roirex.dk>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: f9a23,73ef4cadaafd5728 X-Google-Attributes: gidf9a23,public X-Google-Thread: 10a146,73ef4cadaafd5728 X-Google-Attributes: gid10a146,public From: Erik Peterson <eepeter@erols.com> Subject: Re: i18n and numbers Date: 2000/05/24 Message-ID: <392C0D3C.AEA53AC5@erols.com> X-Deja-AN: 626734279 Content-Transfer-Encoding: 7bit References: <392B9315.B5D7CF66@roirex.dk> X-Accept-Language: en Content-Type: text/plain; charset=big5 X-Complaints-To: abuse@rcn.com X-Trace: njDbVAXNlIiyuiwX+4Ao/tjJD2iFKTIdnu+I8z+sSg302N9iVRt+Eg== Organization: On-line Chinese Tools Mime-Version: 1.0 Reply-To: erik@mandarintools.com NNTP-Posting-Date: 24 May 2000 14:09:36 GMT Newsgroups: comp.lang.java.programmer,dk.edb.programmering.java