vorberechnung?



  • hi
    wenn ich sowas im sourcecode habe:

    int a=10*10*10;
    

    wird das dann zur laufzeit berechnet, oder wandelt der compiler das automatisch in sowas um?

    int a=1000;
    

    wenn ja:
    wird sowas auch bei anderen rechenfunktionen gemacht?
    z.B.:

    float a=sin(532);
    //in
    float a=0,13917310096006544411249666330111f;
    

    wenn nein:
    kann ich das irgendwie erreichen?

    schonmal danke.



  • Sowas ist immer abhängig von Compiler und Einstellungen.

    #include <cmath>
    int main() 
    {
        double a = 10.0 * 10.0;
        double b = std::sin(10.0);
    
        return (int)(a+b);
    }
    

    msvc10 /O2:

    CONST	SEGMENT
    __real@4059000000000000 DQ 04059000000000000r	; 100
    CONST	ENDS
    ;	COMDAT __real@4024000000000000
    CONST	SEGMENT
    __real@4024000000000000 DQ 04024000000000000r	; 10
    ; Function compile flags: /Ogtp
    CONST	ENDS
    ;	COMDAT _main
    _TEXT	SEGMENT
    _main	PROC						; COMDAT
    ; Line 48
    	fld	QWORD PTR __real@4024000000000000
    	call	__CIsin
    ; Line 50
    	fadd	QWORD PTR __real@4059000000000000
    	jmp	__ftol2_sse
    _main	ENDP
    _TEXT	ENDS
    END
    

    10*10 wird also natürlich wegoptimiert. Der Aufruf an sin aber nicht.



  • saraz schrieb:

    hi
    wenn ich sowas im sourcecode habe:

    int a=10*10*10;
    

    wird das dann zur laufzeit berechnet, oder wandelt der compiler das automatisch in sowas um?

    int a=1000;
    

    Kann er, muss er in diesem Fall aber meines Wissens nicht. Die meisten Compiler werden es machen, weil 10*10*10 z.B. auch als compilezeit-Konstante verwendet werden kann und dann direkt berechnet werden muss:

    template <int N> struct foo;
    ...
    foo<10*10*10> f1000; //Compiler initialisiert das template als foo<1000>
    

    wenn ja:
    wird sowas auch bei anderen rechenfunktionen gemacht?
    z.B.:

    float a=sin(532);
    //in
    float a=0,13917310096006544411249666330111f;
    

    Nein. sin ist eine komplexere Mathematische Funktion. Wie die jeweilge Mathebibliothek das genau rechnet ist Sache des Bibliotheksherstellers, nicht des Compilers -> der Compiler kanns zur Compilezeit nicht auflösen.



  • Du kannst den Sinus eines bestimmten Wertes mit Hilfe von Templates zur Compilezeit berechnen lassen, so das in deinem Programm nur noch das Ergebnis auftaucht (es zur Laufzeit nicht berechnet werden muss). Leider ist dies nur eine gute Idee für feste Werte. (Natürlich kannst auch auch einen Taschenrecher verwenden :p)



  • Das nennt sich Constant Folding.

    Es ist auch für komplexere mathematische Funktionen möglich, nur muss es dem Compiler halt für jede Funktion einzeln beigebracht werden. sin wird beispielsweise von gcc seit 4.3 gefoldet - sofern nicht gerade crosskompiliert wird, in welchem Fall das Falten von Fließkommaausdrücken keine triviale Angelegenheit ist (die Darstellung der Zielmaschine könnte von der der Build-Maschine abweichen).



  • pumuckl schrieb:

    der Compiler kanns zur Compilezeit nicht auflösen.

    In speziellen Situationen schon:
    http://en.wikipedia.org/wiki/Intrinsic_function

    sin aber natürlich idR nicht.



  • Also, der GCC kann auch sin(532) auch zur Compile-Zeit berechnen. Ich habe mir zB angewöhnt pi einfach als std::atan(1.0)*4 zu definieren. 😉



  • pumuckl schrieb:

    Wie die jeweilge Mathebibliothek das genau rechnet ist Sache des Bibliotheksherstellers, nicht des Compilers -> der Compiler kanns zur Compilezeit nicht auflösen.

    Aber das Ergebnis sollte immer gleich sein (mit gewisser Fehlertoleranz), deswegen kann er das schon. Zumindest GCC macht es so:

    main:
    	movl	$99, %eax
    	ret
    

    Edit: ups, viel zu spät.


Anmelden zum Antworten