Failure contexts and the Floor() function

I have a four digit integer. I want to separate each digit out into it’s own variable. So instead of x = ‘1234’ I have x1 = ‘1’, x2 = ‘2’, x3 = ‘3’, x4 = ‘4’. My idea (non-Verse, just conceptually) is something like this for x1:

Given x = 1234
x_float = float(x)
x1 = int(Floor(x_float/1000))

I can cast the int to a float by multiplying it by 1.0 (is there a better way?) and the Floor function should return an int, so my question pertains to the Floor() function itself. My first crack at the function was this:

    DecodeTrackerCurrentValue(TrackerValue : int) : int =
        var TrackerFloatValue : float = TrackerValue*1.0
        Digit1 := Floor(TrackerFloatValue/1000.0)
        return Digit1

VSCode shows an issue on TrackerFloatValue/1000.0: ‘Function is invoked with incorrect failure bracketing style.(3511)’ This, I gather, is due to the fact that Floor() is a <decides> function and needs to be wrapped in a failure context. It makes sense to me why this is (since someone could input the wrong data type for instance) but what’s eluding me is how. I’ve been playing around with something like this:

        if (# Some check?):
            Digit1 := Floor(TrackerFloatValue/1000.0)

But I can’t figure out what to put in the parentheses or if this approach is even correct to begin with. Can someone help me understand what I’m trying to do here?

[Edit] Moved to Verse forum

You have to call failable functions like Floor with [] instead of ()
Then you can choose how you want to handle the failure

Option 1: Return a default value if Floor fails

if(Digit1 := Floor[TrackerFloatValue/1000.0]):
    return Digit1
else:
    return 0

Option 2: Return a ?int instead of int

if(Digit1 := Floor[TrackerFloatValue/1000.0]):
    return option{digit1}
else:
    return false?
2 Likes

Excellent, that makes things a lot more clear to me. Thanks!

You can factor an integer into digits with integer division and the integer Mod function. When using integer division, you get a rational number (type rational), which you must use the rational Floor function to get an integer out of.

Here’s a function that returns an array of digits (ordered from most significant to least significant):

GetDigits(I:int)<computes>:[]int=
    if(I=0) then array{}
    else if(Digit := Mod[I, 10]; Residual := Floor(I / 10)):
        GetDigits(Residual) + array{Digit}
    else:
        # This should never be reached because Mod and integer division only fail when the
        # divisor is zero. Nevertheless, the compiler doesn't know that, so this else is needed.
        Err("unreachable")

For example, GetDigits(12345)=array{1, 2, 3, 4, 5}.

3 Likes