(nearly) ieee 754 floating point single precisition

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#31 Post by einstein1969 » 04 Jun 2014 12:13

Thanks penpen!

I have tested the Sin(x) of previus post for see the error.

The result on single test is VERY GOOD! :D

Code: Select all

@echo  off

rem sin(x)

call :sin "1.73"

goto :eof


:sin %1=x radiants

set x=%~1

rem calculate SIN(x) ~ x * ( 1 - x^2 * (1/6 - x^2 * (1/120 - x^2 * (1/5040 - x^2 * (1/362880 - x^2 * 1/39916800 )))))

rem calculate x^2
call :floatTestMul2 "%x%" "%x%"  "xx"

call :floatTestMul2 "%xx%" "2.5052108385441718775052108385442e-8" "sinp"

call :floatTestSub2 "2.7557319223985890652557319223986e-6" "%sinp%" "sinp2"

call :floatTestMul2 "%xx%" "%sinp2%" "sinp3"

call :floatTestSub2 "1.984126984126984126984126984127e-4" "%sinp3%" "sinp4"

call :floatTestMul2 "%xx%" "%sinp4%" "sinp5"

call :floatTestSub2 "0.00833333333333333" "%sinp5%" "sinp6"

call :floatTestMul2 "%xx%" "%sinp6%" "sinp7"

call :floatTestSub2 "0.16666666666666666" "%sinp7%" "sinp8"

call :floatTestMul2 "%xx%" "%sinp8%" "sinp9"

call :floatTestSub2 "1" "%sinp9%" "sinp10"

call :floatTestMul2 "%x%" "%sinp10%" "sin"

echo Sin(%x%)=%sin%

pause

goto :eof

:: functions add for return a value in variable

:floatTestMul2
::   %~1 float string multiplicand1
::   %~2 float string multiplicand2
   setlocal
   set "value1=%~1"
   set "value2=%~2"
 
   call :str2float "%value1%" "float1"
   call :str2float "%value2%" "float2"
   call :floatMul "%float1%" "%float2%" "float3"

   call :intToHex "hex1" "%float1%"
   call :intToHex "hex2" "%float2%"
   call :intToHex "hex3" "%float3%"


   call :float2str "%float3%" "string1"

   rem echo %value1% * %value2% = %float1% * %float2% == %hex1% * %hex2% == %hex3% == %float3% == %string1%

   endlocal & set "%~3=%string1%"
   goto :eof

:floatTestSub2
::   %~1 float string minuend
::   %~2 float string subtrahend
::       else echo hex value if undefined
   setlocal
   set "value1=%~1"
   set "value2=%~2"

   call :str2float "%value1%" "float1"
   call :str2float "%value2%" "float2"
   call :floatSub "%float1%" "%float2%" "float3"

   call :intToHex "hex1" "%float1%"
   call :intToHex "hex2" "%float2%"
   call :intToHex "hex3" "%float3%"


   call :float2str "%float3%" "string1"

   rem echo %value1% - %value2% = %float1% - %float2% == %hex1% - %hex2% == %hex3% == %float3% == %string1%

   endlocal & set "%~3=%string1%"
   goto :eof


result:

Code: Select all

Sin(1.73)=0.9873535


the windows calculator return:
0,98735383970071645108567767622206
0.9873535

I'm very happy :D

You have done a very good work! 8)

EDIT: We have the SIN(x)!!!!

einstein1969

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#32 Post by einstein1969 » 04 Jun 2014 14:48

Hi penpen,

There is another correction to do:

If the second operand %2 of FLOATSUB is 0 the inv is calculated:

Code: Select all

   set /A "inv=(1<<31)^%~2"


result:

Code: Select all

inv = -2147483648


and when this is assigned at variables get the error like "The numbers are limitated at 32bit precision etc..."

einstein1969

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: (nearly) ieee 754 floating point single precisition

#33 Post by penpen » 04 Jun 2014 15:27

einstein1969 wrote:We have the SIN(x)!!!!
Nice 8) !

einstein1969 wrote:(...)
when this is assigned at variables get the error like "The numbers are limitated at 32bit precision etc..."
This is one of the reasons, why i have to revise the code:
This not only could happen in the function :floatSub, ...
it could also happen in many other locations; for example near the starts of :floatAdd :floatMul :intToHex, :float2str - but also within these functions there are some locations where this may happen.

So this time you have to wait for the bugfix; sorry for that.
You should avoid using the float representation of "-0", a hotfix for the floatSub function could be this:

Code: Select all

:floatSub
::   %~1 minuend float in int coding
::   %~2 subtrahend float in int coding
::   %~3 resulting float in int coding
   setlocal
   set /A "value=%~2"
   if "%value%" == "0" (
      set "inv=0"
   else (
      set /A "inv=(1<<31)^%~2"
   )
   call :floatAdd "%~1" "%inv%" "inv"
   endlocal & set "%~3=%inv%"
   goto :eof
But i think this time i won't change the source above,
as it doesn't solve the whole problem, and
as the solution of the problem i plan to use seems to work without changing this function.

penpen

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#34 Post by einstein1969 » 05 Jun 2014 13:08

Hi penpen,

For give a sense at these functions (and test these functions) i have realized a "Plasma" effect.

This is an effect that can show error on visive method. But is nice to look and the work on this is more motivating (at least for me)

Since there is some my workaround on the complete code i don't know if this work.

plasma.cmd (use the ieee754 work):
Image

Code: Select all

@echo off& setlocal EnableDelayedExpansion&Goto :Init_System

:: developed on windows 7 32bit.
:: Use Lucida console 5 for best view

:Main

  call :create_palette

  set /a e=Lenp/2

  for /L %%y in (-30,1,30) do (


    call :str2float "%%y" "fy"

    :: newy=fy/8
    call :floatMul "!fy!" "0x3E000000" newy
    call :float2str "!newy!" "newy"
    call :sin2 "!newy!" siny
    call :str2float "!siny!" "fy"
    call :str2float "!e!" "fe"
    call :floatMul "!fy!" "!fe!" y1
    call :float2str "!y1!" "y1"

    :: get integer part
    set app=!y1:*.=!
    for %%a in (!app!) do set app=!y1:.%%a=!
    if "!app!"=="." set app=0
    set /a iy=e+!app!

    for /L %%x in (-60,1,60) do (

      call :str2float "%%x" "fx"
      call :floatMul "!fx!" "0x3E000000" newx
      call :float2str "!newx!" "newx"
      call :sin2 "!newx!" sinx
      call :str2float "!sinx!" "fx"
      call :str2float "!e!" "fe"
      call :floatMul "!fx!" "!fe!" x1
      call :float2str "!x1!" "x1"

      :: get integer part
      set app=!x1:*.=!
      for %%a in (!app!) do set app=!x1:.%%a=!
      if "!app!"=="." set app=0
      set /a ix=e+!app!
 
      set /a "c=(ix+iy)/2"

      call :plot !c!

    )

   echo(
  )

Goto :EndMain

:sin2 %1=x radiants
   set x=%~1

   if "%x:~0,1%"=="-" (
     set r=-1
     set x=!x:~1!
   ) else (
     set r=1
   )

   rem calculate SIN(x) ~ x * ( 1 - x^2 * (1/6 - x^2 * (1/120 - x^2 * (1/5040 - x^2 * (1/362880 - x^2 * 1/39916800 )))))

   call :str2float "%x%" "fx"

   :: 0x40490FDB=3.14159265....
   call :floatSub "%fx%" "0x40490FDB" "tx"

   if !tx! gtr 0 set /A fx=tx, r=-r

   call :floatMul "%fx%"       "%fx%"       "fxx"
   call :floatMul "%fxx%"      "0x32D7322B" "fsinp"
   call :floatSub "0x3638EF1D" "%fsinp%"    "fsinp2"
   call :floatMul "%fxx%"      "%fsinp2%"   "fsinp3"
   call :floatSub "0x39500D01" "%fsinp3%"   "fsinp4"
   call :floatMul "%fxx%"      "%fsinp4%"   "fsinp5"
   call :floatSub "0x3C088889" "%fsinp5%"   "fsinp6"
   call :floatMul "%fxx%"      "%fsinp6%"   "fsinp7"
   call :floatSub "0x3E2AAAAB" "%fsinp7%"   "fsinp8"
   call :floatMul "%fxx%"      "%fsinp8%"   "fsinp9"
   call :floatSub "0x3F800000" "%fsinp9%"   "fsinp10"
   call :floatMul "%fx%"       "%fsinp10%"  "fsin"

   if !r! lss 0 set /A "fsin=(1<<31)^fsin"

   call :float2str "%fsin%" "sin"

endlocal & set "%~2=%sin%"

goto :eof


:plot %1

 call :color !p[%1]:~0,2! !p[%1]:~-1!

goto :eof


::manual palette
:create_palette %1

  set p=0
  For %%p in (04 4C cE EA A2 21 15 50) do (
 
    set "p[!p!]=%%p°" & set /a p+=1
    set "p[!p!]=%%p±" & set /a p+=1
    set "p[!p!]=%%p²" & set /a p+=1
    set "p[!p!]=%%pÛ" & set /a p+=1

  )

  set /a p-=1
  set Lenp=!p!

goto :eof

Goto :EndMain

:: ( Begin Color Function

:color

    (echo %~2\..\'
    ) > $$$.color.txt && findstr /a:%~1 /f:$$$.color.txt "."

    Shift
    Shift

    If ""=="%~1" Goto :Eof

   goto :color

:: ) End color Fuction


:Init_system

  for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a")
 
  <nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%" > "'"

Goto :Main

:EndMain
  :: Clearing all garbage
  del '
Goto :Eof


EDIT:
This use the code of ieee 754. On first post. Must merge.

Than the other change is the FloatSub.

This is my patch:

Code: Select all

:floatSub
::   %~1 minuend float in int coding
::   %~2 subtrahend float in int coding
::   %~3 resulting float in int coding
   setlocal

   rem echo sub=%1 %2

   rem my temp patch
   if "%~2"=="0" endlocal & set "%~3=%~1" & goto :eof

   set /A "inv=(1<<31)^%~2"

   rem echo inv = %inv%

   call :floatAdd "%~1" "%inv%" "inv"
   endlocal & set "%~3=%inv%"
   goto :eof


or can use the bugfix of penpen. But I have not tested:

Code: Select all

:floatSub
::   %~1 minuend float in int coding
::   %~2 subtrahend float in int coding
::   %~3 resulting float in int coding
   setlocal
   set /A "value=%~2"
   if "%value%" == "0" (
      set "inv=0"
   else (
      set /A "inv=(1<<31)^%~2"
   )
   call :floatAdd "%~1" "%inv%" "inv"
   endlocal & set "%~3=%inv%"
   goto :eof


Sorry for this pieces of code, but this is working progress.

I will post the complete code in the other thread as soon possible.

einstein1969
Last edited by einstein1969 on 05 Jun 2014 19:55, edited 1 time in total.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: (nearly) ieee 754 floating point single precisition

#35 Post by foxidrive » 05 Jun 2014 18:57

It doesn't work as it is missing code...

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: (nearly) ieee 754 floating point single precisition

#36 Post by penpen » 20 Aug 2014 08:14

I have removed some bugs, converted the functions to macros, and split the source into two files:
- floaty.bat (the test cases; the source is at the bottom of this post)
- loadFloat.bat (that contains the macros)

So if you want to use the float functions in your batch file you only need to call "loadFloat.bat" once
and then just use the macros; make sure the extensions are enabled (default on most systems):

Code: Select all

@echo off
setlocal enableExtensions

:: load all macros, and exit if it has failed for whatever reasons
call "loadFloat.bat"
if errorLevel 1 exit /b 1

:: use the macros (names are similar to the function names)
for %%a in (operand1 operand2 result string) do set "%%~a="

%$str2float% "10" operand1
%$str2float% "4"  operand2

%$floatAdd%  "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" + "4" = "%string%"

%$floatSub%  "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" - "4" = "%string%"

%$floatMul%  "%operand1%" "%operand2%" result
%$float2str% "%result%" string
echo("10" * "4" = "%string%"

endlocal

If you want to read the source (more easily), this "toSource.bat" may help:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion
call loadFloat.bat

2>nul md "macros"
for %%a in (str2float float2str floatAdd floatSub floatMul intToHex) do (
   (
      set "firstLine=true"
      for /F "tokens=1* delims=:" %%b in ('set $%%~a ^| findstr /N "^"') do (
         if defined firstLine (
            set "firstLine="
            for /F "tokens=1* delims==" %%d in ("%%c") do (
               set line=%%~e
               echo(
            )
         ) else (
            set line=%%~c
         )
         setlocal enableExtensions enableDelayedExpansion
            set "line=!line:%%=%%%%!"
            echo(!line!
         endlocal
      )
   ) > "macros\%%~a.txt"
)

endlocal


This "floaty.bat" contains the test cases (exceeded the maximum number of allowed characters: 60000):

Code: Select all

@echo off
setlocal enableExtensions  disableDelayedExpansion
call loadFloat.bat
if errorLevel 1 (set error=true)
if defined error exit /b 1

call :floatTest ".e                "
call :floatTest ".e3               "
call :floatTest ".2e               "
call :floatTest "1.e               "
call :floatTest "+.e               "
call :floatTest "+1.e              "
call :floatTest "-.e               "
call :floatTest "-1.e              "

call :floatTest "NaN               "
call :floatTest "+NaN              "
call :floatTest "-NaN              "
call :floatTest "+NaN(7FFFFFFF)    "
call :floatTest "-NaN(7FFFFFFF)    "
call :floatTest "+NaN(FFFFFFFF)    "
call :floatTest "-NaN(FFFFFFFF)    "
call :floatTest "+NaN(FF83FFFF)    "
call :floatTest "-NaN(FF83FFFF)    "
call :floatTest "+NaN(FF83FFFF)    "
call :floatTest "-NaN(FF83FFFF)    "

call :floatTest "inf               "
call :floatTest "+inf              "
call :floatTest "-inf              "

call :floatTest "0.0               "
call :floatTest "-0.0              "

call :floatTest "0x01234567        "
call :floatTest "+0x01234567       "
call :floatTest "-0x01234567       "

call :floatTest "1000.0            "
call :floatTest "1000.00006        "

call :floatTest "0.000001          "
call :floatTest "1.4e-45           "
call :floatTest "4.2E-45           "
call :floatTest "1.1754945E-38     "
call :floatTest "5.877472E-39      "
call :floatTest "12.375            "

call :floatTest "0.0001            "
call :floatTest "0.001             "
call :floatTest "0.01              "
call :floatTest "0.1               "
call :floatTest "1                 "
call :floatTest "10                "
call :floatTest "100               "
call :floatTest "1000              "
call :floatTest "10000             "
call :floatTest "100000            "
call :floatTest "1000000           "
call :floatTest "10000000          "

call :floatTest "68.123            "
call :floatTest "1.17549434E-38    "
call :floatTest "5.877472E-39      "

call :floatTest "-1.0e-6           "

call :floatTest "1.763241500000E-38"
call :floatTest "1.14794E-41       "

call :floatTest "1.4E-45           "

call :floatTest "1.0e10            "
call :floatTest "+1.0e+10          "
call :floatTest "- 1.0 e -10       "

echo(
call :floatTest Add "45.0000" "-45.3000"
call :floatTest Add "100" "0.006"
call :floatTest Add "1.4E-45" "1.1754942E-38"
call :floatTest Add "1.4E-45" "1.4E-45"
call :floatTest Add "1" "2"

echo(
call :floatTest Sub "100" "0.006"
call :floatTest Sub "1.4E-45" "1.1754942E-38"
call :floatTest Sub "1.4E-45" "1.4E-45"
call :floatTest Sub "1" "2"

echo(
call :floatTest Mul "100" "0.1"
call :floatTest Mul "100" "0.05"
call :floatTest Mul "100" "0.005"
call :floatTest Mul "1.4E-45" "1"
call :floatTest Mul "2.8E-45" "0.5"

endlocal
endlocal
goto :eof



:floatTest (overloaded)
::
::   one arguments version: converts the string to a float and back, displaying the results
::   %~1 float string
::
::   three arguments version: performs operand1 operator operand2, displays the result in hex/string
::   %~1 float operator in { "add", "sub", "mul" }  (other operators are ignored)
::   %~2 float string operand2
::   %~3 float string operand1
::
   setlocal enableDelayedExpansion
   set "op=%~1"
   set "A=%~2"
   set "B=%~3"

   if %2. == . (
      for %%a in ("float", "hex", "string") do set "%%~a="

      %$str2float% "%~1%"    float
      %$intToHex%  "!float!" hex
      %$float2str% "!float!" string

      echo(!hex! ^<-- "%~1" --^> "!string!"
   ) else (
      for %%a in ("op", "value1", "value2", "float1", "float2", "float3", "hex1", "hex2", "hex3", "string1") do set "%%~a="
      set "op[add]=+"
      set "op[sub]=-"
      set "op[mul]=*"

      set "op=!op[%~1]!"
      set "value1=%~2"
      set "value2=%~3"

      %$str2float% "!value1!" "float1"
      %$str2float% "!value2!" "float2"

      if        /I "%~1" == "add" (
         %$floatAdd% "!float1!" "!float2!" "float3"
      ) else if /I "%~1" == "sub" (
         %$floatSub% "!float1!" "!float2!" "float3"
      ) else if /I "%~1" == "mul" (
         %$floatMul% "!float1!" "!float2!" "float3"
      ) else (
         endlocal
         goto :eof
      )

      %$intToHex% "!float1!" "hex1"
      %$intToHex% "!float2!" "hex2"
      %$intToHex% "!float3!" "hex3"

      %$float2str% "!float3!" "string1"

      echo !value1! !op! !value2! = !float1! !op! !float2! == !hex1! !op! !hex2! == !hex3! == !float3! == !string1!
   )

   endlocal
   goto :eof

penpen

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#37 Post by einstein1969 » 20 Aug 2014 12:10

Hi penpen,

very nice work 8) but the macro version is slower... :(

This example for execute the code about 3-5X faster.

Code: Select all

@echo off
setlocal enableExtensions

:: load all macros, and exit if it has failed for whatever reasons
call loadfloat.cmd
if errorLevel 1 exit /b 1

:: use the macros (names are similar to the function names)
for %%a in (operand1 operand2 result string) do set "%%~a="

(setlocal EnableDelayedExpansion

   set $str2float=
   set $floatAdd=
   set $float2str=
   set $floatSub=
   set $floatMul=
   set $intToHex=

   rem set |more

   for /F "eol== delims==" %%f in ('set') do set "%%f="

   >t0.$$$.tmp echo !time!

   for /L %%N in (1,1,100) do (

      %$str2float% "10" operand1
      %$str2float% "4"  operand2

      %$floatAdd%  "%operand1%" "%operand2%" result
      %$float2str% "%result%" string
      rem echo("10" + "4" = "%string%"

      %$floatSub%  "%operand1%" "%operand2%" result
      %$float2str% "%result%" string
      rem echo("10" - "4" = "%string%"

      %$floatMul%  "%operand1%" "%operand2%" result
      %$float2str% "%result%" string
      rem echo("10" * "4" = "%string%"

   )

endlocal)

<t0.$$$.tmp set /p "t0="

for /F "tokens=1-8 delims=:.," %%a in ("%t0: =0%:%time: =0%") do set /a "a=(((1%%e-1%%a)*60)+1%

%f-1%%b)*6000+1%%g%%h-1%%c%%d, a+=(a>>31) & 8640000"

echo elapsed cs : %a%

del t0.$$$.tmp

endlocal


And for DIVISION why (for the moment) not implement Newton's Method for finding the reciprocal of a floating point number for division?

other link:
- http://en.wikipedia.org/wiki/Fast_inverse_square_root Fast inverse square root the square of this is the reciprocal!
- http://homepage.cs.uiowa.edu/~jones/bcd/divide.html Reciprocal Multiplication, a tutorial

einstein1969
Last edited by einstein1969 on 20 Aug 2014 16:25, edited 1 time in total.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#38 Post by einstein1969 » 20 Aug 2014 15:55

foxidrive wrote:It doesn't work as it is missing code...



Hi foxidrive,

With the new code i have rewritten the plasma with new gradient.

Code: Select all

@echo off& setlocal EnableDelayedExpansion&Goto :Init_System

:Main

  :: load all macros, and exit if it has failed for whatever reasons
  call loadfloat.cmd
  if errorLevel 1 exit /b 1

  call :create_palette

  set /a e=Lenp/2

  for /L %%y in (-30,1,30) do (


    %$str2float% "%%y" fy

    :: newy=fy/8                                1/4=0x3E800000  1/8=0x3E000000
    rem call :floattestMul2 "1" "0.25" newy

    %$floatMul% "!fy!" "0x3E800000" newy
    %$float2str% "!newy!" newy
    call :sin2 "!newy!" siny
    %$str2float% "!siny!" fy
    %$str2float% "!e!" fe
    %$floatMul% "!fy!" "!fe!" y1
    %$float2str% "!y1!" y1

    :: get integer part
    set app1=!y1:*e-=!

    if not "!y1!"=="!app1!" (set app=0) else (
        set app=!y1:*.=!
        for %%a in (!app!) do set app=!y1:.%%a=!
      )

    if "!app!"=="." set app=0
    set /a iy=e+!app!

    for /L %%x in (-60,1,60) do (

set t0=!time!

      %$str2float% "%%x" "fx"
      %$floatMul% "!fx!" "0x3E800000" newx
      %$float2str% "!newx!" "newx"

set t1=!time!

      call :sin2 "!newx!" sinx

set t2=!time!

      %$str2float% "!sinx!" fx
      %$str2float% "!e!" fe
      %$floatMul% "!fx!" "!fe!" x1
      %$float2str% "!x1!" x1

set t3=!time!

      :: get integer part
      set app1=!x1:*e-=!

      if not "!x1!"=="!app1!" (set app=0) else (
        set app=!x1:*.=!
        for %%a in (!app!) do set app=!x1:.%%a=!
      )

      if "!app!"=="." set app=0
      set /a ix=e+!app!
 
      set /a "c=(ix+iy)/2"

      call :plot !c!

    )

   echo(
  )

Goto :EndMain

:sin2 %1=x radiants
   set x=%~1

   if "%x:~0,1%"=="-" (
     set r=-1
     set x=!x:~1!
   ) else (
     set r=1
   )

   rem calculate SIN(x) ~ x * ( 1 - x^2 * (1/6 - x^2 * (1/120 - x^2 * (1/5040 - x^2 * (1/362880

- x^2 * 1/39916800 )))))

   %$str2float% "%x%" "fx"

:sin2_PI

   :: 0x40490FDB=3.14159265....
   %$floatSub% "%fx%" "0x40490FDB" "tx"

   if !tx! gtr 0 (set /A fx=tx, r=-r) else goto :sin2_cont
   goto :sin2_PI

:sin2_cont

   %$floatMul% "%fx%"       "%fx%"       "fxx"
   %$floatMul% "%fxx%"      "0x32D7322B" "fsinp"
   %$floatSub% "0x3638EF1D" "%fsinp%"    "fsinp2"
   %$floatMul% "%fxx%"      "%fsinp2%"   "fsinp3"
   %$floatSub% "0x39500D01" "%fsinp3%"   "fsinp4"
   %$floatMul% "%fxx%"      "%fsinp4%"   "fsinp5"
   %$floatSub% "0x3C088889" "%fsinp5%"   "fsinp6"
   %$floatMul% "%fxx%"      "%fsinp6%"   "fsinp7"
   %$floatSub% "0x3E2AAAAB" "%fsinp7%"   "fsinp8"
   %$floatMul% "%fxx%"      "%fsinp8%"   "fsinp9"
   %$floatSub% "0x3F800000" "%fsinp9%"   "fsinp10"
   %$floatMul% "%fx%"       "%fsinp10%"  "fsin"

   if !r! lss 0 set /A "fsin=(1<<31)^fsin"

   %$float2str% "%fsin%" "sin"

   set "%~2=%sin%"

goto :eof


:plot %1

 call :color !p[%1]:~0,2! !p[%1]:~-1!

goto :eof


::manual palette, best color add,  rif. http://en.wikipedia.org/wiki/Web_colors
rem
rem 1 -> 2 3 4 5 6 9
rem 2 -> 1 3 4 5 6 A
rem 3 -> 1 2 4 5 6 9 A B
rem 4 -> 1 2 3 5 6 C
rem 5 -> 1 2 3 4 6 9 D
rem 6 -> E
rem 9 -> 1 3 5
rem A -> 2 3 6
rem B -> 3
rem C -> 4 5 6
rem D -> 5
rem E -> 6


:create_palette %1

  set p=0
  rem For %%p in (04 4C cE EA A2 21 15 50) do (
  For %%p in (04 4C c5 53 39 91 15 50) do (
 
    set "p[!p!]=%%p°" & set /a p+=1
    set "p[!p!]=%%p±" & set /a p+=1
    set "p[!p!]=%%p²" & set /a p+=1
    set "p[!p!]=%%pÛ" & set /a p+=1

  )

  set /a p-=1
  set Lenp=!p!

goto :eof

Goto :EndMain

:: ( Begin Color Function

:color

    (echo %~2\..\'
    ) > $$$.color.txt && findstr /a:%~1 /f:$$$.color.txt "."

    Shift
    Shift

    If ""=="%~1" Goto :Eof

   goto :color

:: ) End color Fuction


:Init_system

  for /F "delims==" %%f in ('set') do if /i not "%%f"=="Path" set "%%f="

  for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do

(
  set "DEL=%%a")
 
  <nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%" > "'"

Goto :Main

:EndMain
  :: Clearing all garbage
  del '
Goto :Eof


It's slower than precedent, but it's possible use the trick of "empty the environment" and the trick of "while in a for loop" for achieve a 3-5X faster execute.

EDIT:

this is little optimized code which show how to maintain the env empty even with a call at subroutine.

Code: Select all

@echo off& setlocal EnableDelayedExpansion&Goto :Init_System

:Main

  :: load all macros, and exit if it has failed for whatever reasons
  call loadfloat.cmd
  if errorLevel 1 exit /b 1

  call :create_palette

  set /a e=Lenp/2

  for /L %%y in (-16,1,16) do (

    %$str2float% "%%y" fy

    :: newy=fy/8                                1/4=0x3E800000  1/8=0x3E000000
    rem call :floattestMul2 "1" "0.25" newy

    %$floatMul% "!fy!" "0x3E800000" newy
    %$float2str% "!newy!" newy

    call :sin2 "!newy!" siny

    %$str2float% "!siny!" fy
    %$str2float% "!e!" fe
    %$floatMul% "!fy!" "!fe!" y1
    %$float2str% "!y1!" y1

    :: get integer part
    set app=!y1:*e-=!

    if not "!y1!"=="!app!" (set app=0) else (
        set app=!y1:*.=!
        for %%a in (!app!) do set app=!y1:.%%a=!
      )

    if "!app!"=="." set app=0
    set /a iy=e+!app!
    set app=

    for /L %%x in (-16,1,16) do (

      %$str2float% "%%x" "fx"
      %$floatMul% "!fx!" "0x3E800000" newx
      %$float2str% "!newx!" "newx"

      call :sin2 "!newx!" sinx

      %$str2float% "!sinx!" fx
      %$str2float% "!e!" fe
      %$floatMul% "!fx!" "!fe!" x1
      %$float2str% "!x1!" x1

      :: get integer part
      set app=!x1:*e-=!

      if not "!x1!"=="!app!" (set app=0) else (
        set app=!x1:*.=!
        for %%a in (!app!) do set app=!x1:.%%a=!
      )

      if "!app!"=="." set app=0
      set /a ix=e+!app!
      set app=
 
      set /a "c=(ix+iy)/2"

      call :plot !c!

    )

   echo(
  )

Goto :EndMain

rem calculate SIN(x) ~ x * ( 1 - x^2 * (1/6 - x^2 * (1/120 - x^2 * (1/5040 - x^2 * (1/362880 - x^2 * 1/39916800 )))))

:sin2 %1=x radiants

   call loadfloat.cmd

(
   set $str2float=
   set $floatAdd=
   set $float2str=
   set $floatSub=
   set $floatMul=
   set $intToHex=

   rem set & pause

   set x=%~1

   if "!x:~0,1!"=="-" (
     set r=-1
     set x=!x:~1!
   ) else (
     set r=1
   )

   %$str2float% "!x!" "fx"

   :: PI=3.14159265....=0x40490FDB
   set break=
   for /L %%I in (1,1,10) do if not defined break (
      %$floatSub% "!fx!" "0x40490FDB" tx
      if !tx! gtr 0 (set /A fx=tx, r=-r) else set break=true
   )
   set break=

   %$floatMul% "!fx!"       "!fx!"       fxx
   %$floatMul% "!fxx!"      "0x32D7322B" fsint
   %$floatSub% "0x3638EF1D" "!fsint!"    fsint
   %$floatMul% "!fxx!"      "!fsint!"    fsint
   %$floatSub% "0x39500D01" "!fsint!"    fsint
   %$floatMul% "!fxx!"      "!fsint!"    fsint
   %$floatSub% "0x3C088889" "!fsint!"    fsint
   %$floatMul% "!fxx!"      "!fsint!"    fsint
   %$floatSub% "0x3E2AAAAB" "!fsint!"    fsint
   %$floatMul% "!fxx!"      "!fsint!"    fsint
   %$floatSub% "0x3F800000" "!fsint!"    fsint
   %$floatMul% "!fx!"       "!fsint!"    fsin

   set fsint=
   set fx=
   set fxx=

   if !r! lss 0 set /A "fsin=(1<<31)^fsin"

   %$float2str% "!fsin!" sin

   set "%~2=!sin!"

   set fsin=
   set sin=

goto :eof )


:plot %1

 call :color !p[%1]:~0,2! !p[%1]:~-1!

goto :eof


::manual palette, best transient color,  rif.http://en.wikipedia.org/wiki/Web_colors
rem
rem 1 -> 2 3 4 5 6 9
rem 2 -> 1 3 4 5 6 A
rem 3 -> 1 2 4 5 6 9 A B
rem 4 -> 1 2 3 5 6 C
rem 5 -> 1 2 3 4 6 9 D
rem 6 -> E
rem 9 -> 1 3 5
rem A -> 2 3 6
rem B -> 3
rem C -> 4 5 6
rem D -> 5
rem E -> 6


:create_palette %1

  set p=0
  rem For %%p in (04 4C cE EA A2 21 15 50) do (
  For %%p in (04 4C c5 53 39 91 15 50) do (
 
    set "p[!p!]=%%p°" & set /a p+=1
    set "p[!p!]=%%p±" & set /a p+=1
    set "p[!p!]=%%p²" & set /a p+=1
    set "p[!p!]=%%pÛ" & set /a p+=1

  )

  set /a p-=1
  set Lenp=!p!

goto :eof

Goto :EndMain

:: ( Begin Color Function

:color

    (echo %~2\..\'
    ) > $$$.color.txt && findstr /a:%~1 /f:$$$.color.txt "."

    Shift
    Shift

    If ""=="%~1" Goto :Eof

   goto :color

:: ) End color Fuction


:Init_system

  for /F "delims==" %%f in ('set') do if /i not "%%f"=="Path" set "%%f="

  for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a")
 
  <nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%" > "'"

Goto :Main

:EndMain
  :: Clearing all garbage
  del '
Goto :Eof




EDIT: I have added code optimized for performance.

einstein1969

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: (nearly) ieee 754 floating point single precisition

#39 Post by foxidrive » 22 Aug 2014 11:08

einstein1969 wrote:
foxidrive wrote:It doesn't work as it is missing code...



Hi foxidrive,

With the new code i have rewritten the plasma with new gradient.

einstein1969


It doesn't work here - generates an error and aborts.

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: (nearly) ieee 754 floating point single precisition

#40 Post by einstein1969 » 22 Aug 2014 11:59

:? Can you try the last version? I have written in the other thread. It's simple to debug. Post output in the other thread.

thanks!

Post Reply