Very Large Number to Text Conversion experimental log

This project was in response to this post on the AI2 help board ... [Homework] Convert number to its text

For those who want just to jump to the end of the book, here is the source:

source

https://github.com/AGetzler/number_to_text/blob/main/number_to_text.aia

The first attempt at the interface is simple, with a Text box to receive a number, a Label to show its English expansion, and a Button to trigger the conversion:

Designer (first attempt)

The button Click event starts the conversion process:

The work of conversion is handled in the convert function. Here is my first attempt at it:

convert (first attempt)

Unfortunately, there is a bug in this code that manifests itself only when I get into large negative numbers:

Strangely, the conversion starts off well, until it reaches 809 billion. At that point, it interprets the remainder of the number as eight hundred eleven billion, and wanders off seemingly randomly from there. But when I remove the minus (-) sign, the conversion works perfectly.

The solution to this problem lies in the inner workings of the blue math neg block. It was converting its input into floating point, with a resulting loss of precision, noticeable only in very large numbers. So we need an alternative way to handle a leading '-' sign:

convert (negative corrected)

Notice how I only nibble away a little bit of the problem at each step of the development. It makes testing easier, breaks the big problem down into smaller, easier problems.

This was my first attempt at the convert_positive procedure:

convert_positive (original version)

It has a repetitive pattern in it as it descends through multiple scale levels. See below for a better way.

It is accompanied by smaller helper procedures

convert_power:

Notice that this procedures calls convert_positive , so this is recursive, able to handle indefinitely long numbers, until you run out of memory.

twenty_to_99

This procedure handles numbers in the range 20 to 99.

digit

This procedure handles single digit integers, left of the decimal point.

convert_positive (final version)

The final version of convert_positive handles decimal points, with different handling of the digits before (convert_positive_integer) and after the decimal point (digits) .

digits

Handling of a sequence of digits is tricky, after the decimal point. You have to call out every zero, because they are significant, and you need to space out your words. This procedure is recursive, calling itself.

convert_positive_integer

At this point in the development of the app, we introduce the concept of scale , the biggest power of ten that's less than or equal to the number in question. There are two systems of naming the scales of numbers in English, depending mostly on which side of the Atlantic Ocean is talking:

  • short scale (American)
  • long scale (European)

A List Picker lets you switch your scale (initially the short scale). The scales are loaded from Media files, and the current scale is kept in a dictionary for easy lookup.

global scale_dict

When Screen1.Initialize

When lpkScale.AfterPicking

When File1.GotText

//short_scale.txt

2,hundred
3,thousand
6,million
9,billion
12,trillion
15,quadrillion
18,quintillion
21,sextillion
24,septillion
27,octillion		
30,nonillion

//long_scale.txt

2,hundred
3,thousand
6,million
9,thousand million
12,billion
15,thousand billion
18,trillion
21,thousand trillion
24,quadrillion
27,thousand quadrillion		
30,quintillion

Here we revisit convert_positive_integer to see how it picks the best scale and applies that.

top_scale

This is a step function, which loops through scale_dict searching for the largest key (2,3,6,9,...) for which 10^key <= n for the given number n. A step function looks like a staircase from the side, with flat sections like steps.

If we got a non-zero scale, we have a big number, and have to use convert_power

convert_power

Sample run, with the works

5 Likes