I was cleaning up some script files, I'd forgotten to publish a partially, buggy implementation of
RFC8135 produced that above output.
Basically it uses two functions right now:
$tofloat <str or num> - from a string to a "fakefloat" ( the "ip6" type in ROS)
$fromfloat <ip6> - takes a variable, internally a ip6 type, created by $tofloat to output it as floating/decimal number as string.
There are NO math functions yet, like $ADD <fakefloat>... or $MULTIPLY. And $fromfloat should take an arg like "round=0" to get the integer part or truncate the decimal part. Targeting a 4/1 release for those.
And borrows/adapts the following helpers, which may be more helpful as functions:
$tobase <num> base=[1-32, optional] - used to convert base10 to base16 hexstrings
$strip <string> strip=<char to strip> - used to remove ":" in ip6 addresses.
:global tofloat do={
:global tobase;
:local i;
:local d;
:local ip6comp 1000
if ($1~"-") do={
:set ip6comp 1001
:set $1 [pick $1 1 99]
}
:if ([typeof $1]~("num")) do={
:set $i $1;
:set $d 0;
} else={ :if ([find $1 "."]>0) do={
:set i [pick $1 0 [find $1 "."]]
:set d [pick $1 ([find $1 "."]+1) 64]
} else={:set $i 0; set $d 0;}
}
:local ihex [$tobase $i]
:local dhex [$tobase $d]
:local float64 [:toip6 "$ip6comp:$dhex::$ihex"]
#:put "$ihex $dhex $i $d $float64"
:return $float64
}
:global fromfloat do={
:global strip
:local float64 [tostr $1]
:local neg ""
:if ($float64~"1001.+") do={:set $neg "-"}
:set $float64 [pick $float64 5 64]
:local ipart [$strip char=":" [pick $float64 ([find $float64 "::"]+2) 64]]
:local dpart [$strip char=":" [pick $float64 0 ([find $float64 ":"]+1)]]
#if ([typeof [tonum $dpart]]!="num") do={set dpart 0}
#:put "$float64 $neg $ipart $dpart"
:set ipart [tonum "0x$ipart"]
:set dpart [tonum "0x$dpart"]
:local strfloat "$neg$ipart.$dpart"
#:put "$strfloat $ipart $dpart"
:return $strfloat
}
# adapted from msmater https://forum.mikrotik.com/viewtopic.php?t=160989#p792240
:global strip do={
:local a [tostr $1]
:local b $char
:if ([typeof $b]="nil") do={:set b "-"}
:while ([find $a $b]) do={
:set $a ("$[:pick $a 0 ([find $a $b]) ]"."$[:pick $a ([find $a $b]+1) ([:len $a])]")}
:return $a
}
# adapted from System_Convert-Decimal-BaseX by Randy Graham
# :put [$tobase 32 base=16]
:global tobase do={
:local decnum $1
:local basenum ""
:if ([typeof $base]="nil") do={:local base 16} else={:local base}
:if ($base>0 and $base<33) do={} else={:set $base 16}
:local chrtable [:toarray "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f"]
:local chrtable ($chrtable + [:toarray "g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"])
:local basedigits 0
:local basearray
:local bw
:local loop 1
:while ($loop=1 ) do={
:set bw 0
:for c from=0 to=$basedigits step=1 do={
:set bw ($bw*$base)
:if ($bw=0) do={:set bw 1}
}
:set basearray ($basearray + [:toarray $bw])
:set bw ($decnum/$bw)
:if ($bw > 0) do={
:set basedigits ($basedigits+1)
} else={
:set loop 0
:set basedigits ($basedigits-1)
}
}
:local dn $decnum
:local bpv
:for c from=$basedigits to=0 do={
:set bpv ($dn/[:pick $basearray $c])
:set dn ($dn-([:pick $basearray $c]*$bpv))
:set basenum "$basenum$[:pick $chrtable $bpv]"
}
:return $basenum
}
If you save that to the router as a file called "fakefloat", usage like:
:import fakefloat
:global myfloat [$tofloat -10.1]
:put [$fromfloat $myfloat]
# -10.1
With some tests like this:
:put "$([$tobase 1]) $([$tobase 10]) $([$tobase 16]) $([$tobase 16 base=32])"
:put "stripchar $([$strip char=":" "1:1:1:1" ])"
:put [$fromfloat [toip6 "1000:1::1"]]
:put [$fromfloat [toip6 "1001:1::1"]]
:put [$fromfloat [toip6 "1000:10::10"]]
:put [$fromfloat [toip6 "1001:10::10"]]
:put [$fromfloat [:toip6 "1001:03e9::1"]]
:put [$fromfloat [:toip6 "1001:1::03e9"]]
:put [$fromfloat [:toip6 "1000:540::10f7"]]
:put [$tofloat 0]
:put [$tofloat 1.1]
:put [$tofloat -1.1]
:put [$tofloat -123.-123]
:put [$tofloat 4343.1344]
:put [$fromfloat [$tofloat 0]]
:put [$fromfloat [$tofloat 1.1]]
:put [$fromfloat [$tofloat -1.1]]
:put [$fromfloat [$tofloat -123.123]]
:put [$fromfloat [$tofloat 4343.1344]]
* only tested on V7.x