🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.java.programmer
Article #633

Re: i18n and numbers

#633
From: Erik Peterson
Date: Wed, 24 May 2000 00:00
272 lines
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-mail
References: <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