Version 0 of Hebrew numbers

Updated 2001-12-10 08:25:15

Richard Suchenwirth - In the Hebrew system of writing numbers, as used in Israel, the letters of the alphabet are assigned numeric values (1 through 9, 10 through 90, 100 through 400). Higher numbers are expressed by addition (e.g. 900=400(+)400(+)100), and numbers above 1000 are written as high-order part (multiplied by 1000) 'tick' low-order part, where the above rules apply for both parts. (I assume this is repeated for numbers over 1 million). The following implementation takes a positive integer and returns the Hebrew number as a string of Unicodes. The exceptions that 15 is written as 6(+)9, 16 as 7(+)9, are handled in the final string map command. Note that as zeroes are not expressed, I could use the first position (index 0) of each range list as a sort of "data-comment", which increases readability even if looking unusual for Tcl (or in fact, any language I'm aware of).

 proc iw'format i {
    if {$i >= 1000} {
        set res [iw'format [expr {$i%1000}]]�[iw'format [expr $i/1000]]
    } elseif {$i >= 400} {
        set res [iw'format [incr i -400]]\u05EA
    } else {
        set res ""
        foreach digit [lrevert [split $i ""]] range {
{ones
\u05d0 \u05d1 \u05d2 \u05d3 \u05d4 \u05d5
                       \u05d6 \u05d7 \u05d8}
{tens
\u05d9 \u05db \u05dc \u05de \u05e0 \u05e1
                       \u05e2 \u05e4 \u05e6}
            {hundreds: \u05e7 \u05e8 \u05e9 \u05EA}
        } {
            if {$digit!="" && $digit!=0} {
                append res [lindex $range $digit]
            }
        }
    }
    string map {\u05d4\u05d9 \u05d5\u05d8 \u05d5\u05d9 \u05d6\u05d8} $res
 }

if 0 {In the opposite direction, turning a numeric Hebrew string into an integer, the task was even easier as strict addition could be performed:}

 proc iw'scan iwnum {
    set res 0
    set factor 1
    array set value {
        \u05d0 1 \u05d1 2 \u05d2 3 \u05d3 4 \u05d4 5 \u05d5 6
        \u05d6 7 \u05d7 8 \u05d8 9 \u05d9 10 \u05db 20 \u05dc 30
        \u05de 40 \u05e0 50 \u05e1 60 \u05e2 70 \u05e4 80 \u05e6 90
        \u05e7 100 \u05e8 200 \u05e9 300 \u05ea 400
    }
    foreach group [split $iwnum �'] {
        set sum 0
        foreach char [split $group ""] {
            incr sum $value($char)
        }
        set res [expr {$res + $sum * $factor}]
        set factor [expr {$factor * 1000}]
    }
    set res
 }

if 0 {Note that both procedures produce or read Hebrew so it "looks right" (from right to left) in Tk widgets, but in Unicode terms, this is wrong - strings in memory should always be in the correct logical direction, and the bi-directional rendering is a task of the final rendering software. As soon as Tk does correct "bidi" treatment, the output of iw'format or the group list of iw'scan will have to be reverted.}


Heblish - Natural languages - Arts and crafts of Tcl-Tk programming