Proposal: fixing the 'pure' floating point problem.

Michel Fortin michel.fortin at michelf.com
Mon Mar 16 04:39:30 PDT 2009


On 2009-03-16 04:03:01 -0400, Don <nospam at nospam.com> said:

>> In Don's proposal, the following is legal:
>> 
>> -------------------------
>> module A(floatingpoint);
>> pure void a()
>> {
>>      set mode;
>>      b();
>>      restore mode;
>> }
>> ------------------------
>> module B(floatingpoint);
>> pure void b()
>> {
>>      do stuff;
>> }
>> -------------------------
>> 
>> because, from compiler's perspective, they're
>> 
>> struct FpuState { mode; sticky; }
>> pure FpuState a(FpuState s);
>> pure FpuState b(FpuState s);
>> 
>> and can be actually cached, if compiler so wishes.  IIUC, this is
>> exactly the use case when you implement range arithmetics.
> 
> Hooray! Someone's understood the proposal.


Interestingly, it's almost the same thing as I proposed earlier in this 
thread. In my proposal what you can declare floating-point-flag-neutral 
are functions instead of modules, and you wouldn't need a statement to 
set and restore the mode as it'd be done automatically when calling a 
function declared for a given mode. Said mode could be explicit or 
neutral, the latter meaning the function accepts any mode.

My thinking is that forcing flag changes on function boundaries should 
make it easier for the compiler than set/restore statements, while 
ensuring they're properly scoped.

Here's what it could look like:

	pure float a()  // floatmode(round_nearest)  is assumed when omitted
	{
		// compiler sets the float mode to round down according to b's declaration.
		b(); // now can call b with the right mode
		// compiler restores float mode to round_nearest (this function's mode)
		// calls to b can be easily memoized since b always use the same float mode
	}

	pure float b() floatmode(round_down)
	{
		return c(1); // call c with the current settings (becuase c is 
float-mode-neutral)
		// calls to c can be memoized within the boundaries of b because the round
		// mode won't change inside b.
	}

	pure float c(float) floatmode(neutral)
	{
		// do stuff in the caller's floating point mode
	}


And to set all functions in a module as being float-mode-neutral, do it 
like like you'd do for extern(C), or pure:

	module std.math;

	floatmode(neutral):

	// write you functions here.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list