Canister called `ic0.trap` with message: 'losing precision'

What is this error? How to correct it?

Canister called `ic0.trap` with message: 'losing precision'.

Suspected code:

        switch(await CyclesLedger.icrc1_transfer({
            to = {owner = Principal.fromActor(this); subaccount = null};
            fee = null;
            memo = null;
            from_subaccount = ?(Principal.toBlob(user));
            created_at_time = ?(Nat64.fromNat(Int.abs(Time.now())));
            amount = Int.abs(Float.toInt(Float.fromInt(amountToMove) * (1.0 - env.revenueShare)));
        })) {
            case (#Err e) {
                Debug.trap("transfer failed: " # debug_show(e));
            };
            case (#Ok _) {};
        };
        // Pay to the vendor (TODO: Ensure no double fee later.)
        switch(await CyclesLedger.icrc1_transfer({
            to = {owner = revenueRecipient; subaccount = null};
            fee = null;
            memo = null;
            from_subaccount = ?(Principal.toBlob(user));
            created_at_time = ?(Nat64.fromNat(Int.abs(Time.now())));
            amount = Int.abs(Float.toInt(Float.fromInt(amountToMove) * env.revenueShare));
        })) {
            case (#Err e) {
                Debug.trap("transfer failed: " # debug_show(e));
            };
            case (#Ok _) {};
        };

env.revenueShare == 0.05.

did you try hardcoding the value instead of using the .env?
also could be, multiple data type conversions in Motoko often leads to these kind of errors

I use env/lib.mo module. That’s hardcoding.

“also could be, multiple data type conversions in Motoko often leads to these kind of errors” - no idea what you mean.

I mean hardcoding the float, and with data conversions I mean that sometimes (or often times) you have a float that you need to convert to Nat or Int or viceversa. But idk I’m just guessing based on your code.

We trap with this error message when you attempt to do a lossy convertion, e.g Nat64.fromNat(n) when n is not in the correct range for a Nat64 [0 .. 2^64). Not sure which operation is raising it here though.

Must be these two: Float.toInt(Float.fromInt(....

Motoko has 64-bit Floats, with a 52bit mantissa. When the exponent is not 0, there are $2^ exponent$ possible integers to convert to. My hunch is that this is causing the trouble.

I’ve found the error. It was in another part of the program:

I was converting Nat to Nat32 without ensuring 32-bit size.

1 Like