Floating Point Intermediate Values
On many computers, greater precision operations do not take any longer than lesser precision operations, so it makes numerical sense to use the greatest precision available for internal temporaries. The philosophy is not to dumb down the language to the lowest common hardware denominator, but to enable the exploitation of the best capabilities of target hardware.
For floating point operations and expression intermediate values, a greater precision can be used than the type of the expression. Only the minimum precision is set by the types of the operands, not the maximum. Implementation Note: On Intel x86 machines, for example, it is expected (but not required) that the intermediate calculations be done to the full 80 bits of precision implemented by the hardware.
It's possible that, due to greater use of temporaries and common subexpressions, optimized code may produce a more accurate answer than unoptimized code.
Algorithms should be written to work based on the minimum precision of the calculation. They should not degrade or fail if the actual precision is greater. Float or double types, as opposed to the extended type, should only be used for:
-
reducing memory consumption for large arrays
-
data and function argument compatibility with C
In existing languages, there is an astonishing amount of effort expended in trying to jam a complex type onto existing type definition facilities: templates, structs, operator overloading, etc., and it all usually ultimately fails. It fails because the semantics of complex operations can be subtle, and it fails because the compiler doesn't know what the programmer is trying to do, and so cannot optimize the semantic implementation.
This is all done to avoid adding a new type. Adding a new type means that the compiler can make all the semantics of complex work "right". The programmer then can rely on a correct (or at least fixable ) implementation of complex.
Coming with the baggage of a complex type is the need for an imaginary type. An imaginary type eliminates some subtle semantic issues, and improves performance by not having to perform extra operations on the implied 0 real part.
Imaginary literals have an i suffix:
imaginary j = 1.3i;
There is no particular complex literal syntax, just add a real and imaginary type:
complex c = 4.5 + 2i;
Adding two new types to the language is enough, hence complex and imaginary have extended precision. There is no complex float or complex double type, and no imaginary float or imaginary double. [NOTE: the door is open to adding them in the future, but I doubt there's a need]
Complex numbers have two properties:
.re get real part as an extended
.im get imaginary part as an imaginary
For example:
c.re is 4.5
c.im is 2i
Rounding Control
IEEE 754 floating point arithmetic includes the ability to set 4 different rounding modes. D adds syntax to access them: [blah, blah, blah] [NOTE: this is perhaps better done with a standard library call]
Exception Flags
IEEE 754 floating point arithmetic can set several flags based on what happened with a computation: [blah, blah, blah]. These flags can be set/reset with the syntax: [blah, blah, blah] [NOTE: this is perhaps better done with a standard library call]
Floating Point Comparisons
In addition to the usual < <= > >= == != comparison operators, D adds more that are specific to floating point. These are [blah, blah, blah] and match the semantics for the NCEG extensions to C.
[insert table here]
D x86 Inline Assembler
http://www.digitalmars.com/gift/index.htmlD, being a systems programming language, provides an inline assembler. The inline assembler is standardized for D implementations across the same CPU family, for example, the Intel Pentium inline assembler for a Win32 D compiler will be syntax compatible with the inline assembler for Linux running on an Intel Pentium.
Differing D implementations, however, are free to innovate upon the memory model, function call/return conventions, argument passing conventions, etc.
This document describes the x86 implementation of the inline assembler.
AsmInstruction:
Identifier : AsmInstruction
align IntegerExpression
even
naked
db Operands
ds Operands
di Operands
dl Operands
df Operands
dd Operands
de Operands
Opcode
Opcode Operands
Operands
Operand
Operand , Operands
Labels
Assembler instructions can be labeled just like other statements. They can be the target of goto statements. For example:
void *pc;
asm
{
call L1 ;
L1: ;
pop EBX ;
mov pc[EBP],EBX ; // pc now points to code at L1
}
align IntegerExpression
Causes the assembler to emit NOP instructions to align the next assembler instruction on an IntegerExpression boundary. IntegerExpression must evaluate to an integer that is a power of 2.
Aligning the start of a loop body can sometimes have a dramatic effect on the execution speed.
even
Causes the assembler to emit NOP instructions to align the next assembler instruction on an even boundary.
naked
Causes the compiler to not generate the function prolog and epilog sequences. This means such is the responsibility of inline assembly programmer, and is normally used when the entire function is to be written in assembler.
Share with your friends: |