Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
ShowAll Questionssorted byDate Posted
Sabrent

# Math Function

can someone please explain to me how this code is conerting String to word. I would apprecite you rhelp.Thanks

```//Takes a Number as a String, and makes it into the word number.
public String toWords(String s){
String[] th = new String[]{'','thousand','million', 'billion','trillion'};
String[] dg = new String[]{'zero','one','two','three','four', 'five','six','seven','eight','nine'};
String[] tn = new String[]{'ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'};
String[] tw = new String[]{'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'};

s = s.replace(',','');
Integer x = 0;
x = s.indexOf('.');
if (x == -1) x = s.length();
if (x > 15) return 'too big';
String[] qr = s.split('');
Integer[] n = new Integer[0];
for (Integer i=1;i < qr.size();i++){
}
String str = '';
Integer sk = 0;
for (Integer i=0; i < x; i++) {
if (math.mod(x-i,3)==2){
if (n[i] == 1) {
str += tn[n[i+1]] + ' ';
i++; sk=1;
}
else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';
sk=1;
}
}
else if (n[i]!=0) {
str += dg[n[i]] +' ';
if(math.mod(x-i,3)==0) str += 'hundred ';
sk=1;
}
if(math.mod(x-i,3)==1){
if (sk==1) str += th[(x-i-1)/3] + ' ';
sk=0;
}
}
if (x != s.length()) {
Integer y = s.length();
str += 'point ';
for (Integer i=x+1; i<y; i++) str += dg[n[i]] +' ';
}
return str;

}```

﻿

mulveling

Yeah, that's a bit tough to read -- but still nothing compared to the massively insane logic some of the Scientific Computing folks write.

Unfortunately, what constitutes good optimization on traditional platforms can be extremely counter-productive in Apex, since the REAL bottleneck here is # of script statements -- and sometimes, stack depth -- and rarely, heap size.

Here's my first rough stab at a slightly more human-readable Apex version of "number wordify" -- clearly it can be refined, optimized, and cleaned up further:

```public class Options {
public String hundred = ' hundred';
public String zero = 'zero';
public String andJoin = ' and ';
public String plainJoin = ' ';
public String hyphenJoin = '-';
public String intDecJoin = ', ';
public String[] ones = 'zero one two three four five six seven eight nine ten'.split(' ');
public String[] teens = ('ten eleven twelve thirteen fouteen fifteen sixteen seventeen ' +
'eighteen nineteen').split(' ');
public String[] tens = '  twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ');
public String[] qualifiers = ('thousand million billion trillion quadrillion quintillion ' +
'sextillion septillion octillion nonillion decillion undecillion duodecillion ' +
'tredecillion quattuordecillion quindecillion sexdecillion septendecillion ' +
'octodecillion novemdecillion vigintillion').split(' ');
public String qualifierJoin = ', ';
public String point = 'point';
public String pointJoin = plainJoin + point;
}
public String[] chars(String str) {
String[] chars = str.split('');
if (chars.size() > 0) {
chars.remove(0);
}
return chars;
}
public class FormatException extends Exception {}
public static String wordifyDecimal(String strNumber) {
return wordifyDecimal(new Options(), strNumber);
}
public static String wordifyDecimal(Options opts, String strNumber) {
Integer decimalIndex = strNumber.indexOf('.');
if (decimalIndex >= 0) {
String decimalWords = '';
// strip trailing zeros from the decimal component:
String strDecimal = strNumber.substring(decimalIndex + 1, strNumber.length()).
replaceAll('([^0])[0]+\$', '\$1');
for (Integer i=0; i < strDecimal.length(); i++) {
decimalWords += (i > 0 ? opts.hyphenJoin : '') +
opts.ones[Integer.valueOf(strDecimal.substring(i, i+1))];
}
return wordifyInt(opts, strNumber.substring(0, decimalIndex)) +
(decimalIndex > 0 ? opts.pointJoin : opts.point) + opts.plainJoin +
decimalWords;
}
return wordifyInt(new Options(), strNumber);
}

public static String wordifyInt(String strInt) {
return wordifyInt(new Options(), strInt);
}
public static String wordifyInt(Options opts, String strInt) {
strInt = strInt == null ? '' : strInt.replaceAll('\\s', '');
if (strInt == '') {
return strInt;
}
// ensure we've got a valid int:
if (!Pattern.compile('\\d+').matcher(strInt).matches()) {
throw new FormatException('Invalid integer: ' + strInt);
}
strInt = strInt.replaceAll('^[0]+', '');
if (strInt == '') {
return opts.zero;
}
// break the integer up into millenial chunks of 3 digits, starting from the
// least-significant (i.e. right-most) digit:
String buffer = '';
Integer qualifierIndex = -1;
for (Integer i=strInt.length() - 3; i >= -2; i -= 3) {
if (qualifierIndex >= opts.qualifiers.size()) {
throw new FormatException('Integer is too long');
}
// left-pad-0 as necessary, if we're on our most significant chunk:
String[] chars = chars((i == -2 ? '00' : (i == -1 ? '0' : '')) +
strInt.substring(Math.max(0, i), i + 3));
String chunk = wordifyMillenia(opts, new Integer[]{
Integer.valueOf(chars[0]), Integer.valueOf(chars[1]), Integer.valueOf(chars[2])});
buffer = chunk + (qualifierIndex >= 0 ? opts.plainJoin + opts.qualifiers[qualifierIndex] +
opts.qualifierJoin : '') + buffer;
qualifierIndex++;
}
return buffer;
}
// takes in 3 digits representing a "millenia", with index 0 being the most significant
// digits (i.e. hundreds) and first breaks it down into an array of 3 string 'bits', some
// or all of which may be null -- e.g. 805 => {'eight', null, 'five'}, 034 =>
// {null, 'thirty', 'four'}, 217 => {'two', 'seventeen', null} -- and then joins those bits according
// to options.
public static String wordifyMillenia(Options opts, Integer[] digits) {
String[] bits = new String[]{null, null, null};
// hundreds column:
if (digits[0] > 0) {
bits[0] = opts.ones[digits[0]];
}
// tens column:
if (digits[1] == 1) {
// 1 in the decades column -- e.g. eleven, sixteen:
bits[1] = opts.teens[digits[2]];
return joinBits(opts, bits);
} else if (digits[1] > 1) {
bits[1] = opts.tens[digits[1]];
}
// ones column:
if (digits[2] > 0) {
bits[2] = opts.ones[digits[2]];
}
return joinBits(opts, bits);
}
public static String joinBits(Options opts, String[] bits) {
String buffer = '';
if (bits[0] != null) {
buffer += bits[0] + opts.hundred;
}
if (bits[1] != null) {
buffer += (bits[0] != null ? opts.andJoin : '') + bits[1] +
(bits[2] != null ? opts.hyphenJoin + bits[2] : '');
} else if (bits[2] != null) {
buffer += (bits[0] != null ? opts.andJoin : '') + bits[2];
}
return buffer;
}

System.debug(wordifyDecimal('0078645100514708413.1400'));
System.debug(wordifyDecimal('00.098334'));
System.debug(wordifyDecimal('1234'));
System.debug(wordifyDecimal('3.14'));
System.debug(wordifyDecimal('603'));
```

--

Mike

Sabrent

Steve, Thanks for the elaborate explanation. Though i am still trying to understand, it is indeed more readable.

mulveling

The name is Mike :)