August 3, 2014

0.4.3: Floating point support

After a long time having only partial floating point support in Red/System, it comes now to Red with a broader support, thanks to the terrific work from Qtxie and Oldes, who managed to push Red further while I was busy moving from Europe to China (though, this might be the topic for another blog entry, as requested by many of you).

The new float! datatype implements IEEE-754 64-bit floating point format. It is available with most of the usual math functions support:

  • infix operators: +, -, *, /, **.
  • prefix base functions: add, substract, multiply, divide, power.
  • trigonometric functions:  cosine, sine, tangent, arcsine, arccosine, arctangent.
  • other math functions: log-2, log-10, log-e, exp, square-root, round

Note that these trigonometric functions are taking arguments in degrees, a /radians refinement is provided for input values in radians. However, this can result in extra verbosity for some long math expressions where using only radians, like:
((sine/radians b) * (cosine/radians c)) + ((cosine/radians b) * (sine/radians c))
Some radians-oriented shortcuts to these functions are also provided for convenience: cos, sin, tan, arcsin, arccos, arctan. So the above expression becomes:
((sin b) * (cos c)) + ((cos b) * (sin c))
Here are some code examples from Red console:
red>> 1.23456
== 1.23456
red>> 1e10
== 10000000000.0
red>> 1.23 * 2
== 2.46
red>> 1.23 * 2.0
== 2.46
red>> to integer! 1.23 * 2.0
== 2
red>> cos pi
== -1.0
red>> sin pi
== 0.0
red>> cos pi / 2
== 0.0
red>> cos pi / 3
== 0.5
red>> cosine/radians pi / 3
== 0.5
red>> cosine 60
== 0.5
red>> .1 + .2 + .3
== 0.6
red>> .1 + .2 + .3 = .6
== true
red>> .1 + .2 + .3 - .6
== 1.110223024625157e-16
red>> float? load "0.1"
== true
red>> to float! 1
== 1.0
red>> 1 = to integer! to float! 1
== true
As you can see, Red tries to give you meaningful outputs even when the result is not exact, but this approach has its limits too. Qtxie has ported partially dtoa() functions to Red/System, however, the overhead of the additional code (20-40KB once compiled) is quite costly given how tiny is currently our runtime library (~350KB). So, for now, that implementation has been provided as an optional library for Red/System, and will be modularized for Red, once modules will be supported.

IEEE-754 special values

You might know that standard floating point format supports a few extra special values that are meant to make some calculation possible in edge cases. Those are also supported natively by Red, with the following literal formats:
Not a Number (NaN)        :  1.#NaN
Positive Infinity (+INF)  : +1.#INF (or just 1.#INF)
Negative Infinity (-INF)  : -1.#INF
Positive Zero             : +0.0 (or just 0.0)
Negative Zero             : -0.0
These values are mostly intended for scientific calculations, you do not have to worry about them. They can be produced as results of some math operations on floats, but by default, an error will be thrown instead.

In case, you need to operate with maximum precision, and have all the special float values as results instead of errors, a couple of flags are available for that through the system special access. The syntax is:
system/float-options [spec]

[spec]: block of flags (word! | set-word!) with values (logic! | word!)
Valid flags are:

  • pretty?: enables pretty printing of float numbers when very close to an integer value (default: true)
  • full?: enables math operations on float special values (default: false)

 Examples:
red>> 4.000000000000001e32
== 4.0e32
red>> system/float-options [pretty?: no]
red>> 4.000000000000001e32
== 4.000000000000001e32
Armhf support

So far, Red supported only the armel ABI for ARM backends. Since this release, we fully support now armhf ABI too, through a specific compilation option that can be found in the new RPi compilation target (intended mainly for default OS on RaspberryPi). The main difference between these ABI is the way float values are passed as arguments to functions, armel requires passing them on stack, while armhf requires passing them through FPU registers.

Other changes

  • url! datatype preliminary support: all actions are working, but no path access support yet.
  • New actions: reverse, random, swap, take, to(*), trim
  • New natives: same?, NaN?
  • New mezzanines: float?, routine?
  • Red/System FPU direct access through system/fpu/* options.
  • Help command now displays full help on routines too.
  • Many bug fixes and a few wishes granted.

(*) to is currently limited to integer/float/string conversions only.

What's next?

After the digression in the floating point lands, we go back to our main roadmap, so in the next releases, expect (in no particular order):

  • GUI support for Android / Windows platforms
  • Improved toolchain for Android APK generation
  • Object compilation support
  • New console engine
  • Error! datatype and exceptions handling
  • Typeset! and other new datatypes
  • Redbin format specification and implementation for the compiler
  • Improved compiler performance

Thanks for your patience and support during these last months, we are now back to our cruise development speed, so expect faster changes until the end of the year.

10 comments:

  1. Félicitations ! Je vais tester ça de suite :)

    ReplyDelete
  2. Great!!
    GUI support!!! Does that mean a Rebol/View -like version is on its way? (newbee...)

    ReplyDelete
  3. Andrew: I think that what is actually planned is VID like dialect, but no View AGG library based engine. Red is going to use native platform widgets. It is better for conventional apps, whereas in areas like free drawing etc., where AGG excells, we might be a bit lacking ...

    ReplyDelete
  4. Red is going to have by default a GUI that allows you to build apps with native widgets and do vector drawing using the hardware-accelerated API provided by the OS, instead of a dead and software-only library like AGG (not mentioning the GPL incompatible license of that library).

    ReplyDelete
    Replies
    1. Alright, that's good news!!! Still learning in Rebol/View for now, but closely following Red to assure myself for the future :-)
      Thanks!

      Delete
  5. I like the shortcuts for the radian forms (radians are better anyway).

    But to be forward looking, perhaps you should include TAU and define PI as being TAU/2!

    http://blog.hostilefork.com/clocks-that-run-backwards/

    ReplyDelete
  6. Very cool. I wonder why arctangent instead of atan, and degrees of radians. I would think the first is much shorter and just as clear/unique while the second is closer to the language of math.

    Best Wishes

    ReplyDelete
    Replies
    1. Sorry, imprecise reading of the post! The first point still stands: 'a' might be preferable to 'arc' for the radian versions.

      Delete
    2. "arctangent instead of atan" That's a typo, should be "arctan", it is fixed now.

      Indeed, "a" prefix instead of "arc" would be more consistent (as we already provide a shortcut form) for the radians versions.

      Delete

Fork me on GitHub