Bartku, pomyliłem się, sądziłem że chodziło o użycie 32 bitowych zmiennych, a nie 64-ro. Stad moja wątpliwość.
Float i Double w WinAVR są oczywiście 32 bitowe, co zapewnia dokładność 7-dmiu pierwszych cyfr (dziesiętne).
Ciekawe czy któryś z kompilatorów dla Double, przyjmuje 64 bity.
--------------------------------------------------------------
Adamie,
W przypadku 64-bitowów uzyskałem dokładnie
0x0CCCCCCC, a w przy 32-bitach podbnie jak ty
0x0CCCCCD0
Kod wersji 64-bitowej:
Kod:
#include <stdint.h>
#include <avr/io.h>
int main(void)
{
uint64_t Fclk=400000000;
uint64_t Fvfo=20000000;
uint32_t FTW;
FTW=(uint32_t)((uint64_t)0x100000000*Fvfo/Fclk);
return 0;
};
Dodaję również pliki wynikowe, podziel się Adamie opinią o nich.
BASCOM (wer. 2.0.5.0) okazał się jeszcze inny:
Można w nim bez problemu usunąć tablicę przerwań i czyszczenie całej pamięci:
Kod testu wygląda tak:
Kod:
$noinit
$noramclear
$regfile "m32def.dat"
$crystal = 16000000
Const Fclk = 400000000
Const Fvfo = 20000000
Dim Pom As Single
Dim Pom2 As Single
Dim Ftw As Dword
Pom = &H100000000
Pom2 = Fvfo
Pom = Pom * Pom2
Pom2 = Fclk
Pom = Pom / Pom2
Ftw = Pom
End
Kod: 738 (40+698)
Cykle: 1 385 (20+1365) (~87ns)
Wynik: oczywiście
0x0CCCCCD0
BASCOM ma jednak coś o czy pisałem powyżej, czyli obsługę dokładniejszych zmiennych zmiennoprzecinkowych.
Kod z wykorzystanie lepszych zmiennych zmiennoprzecinkowych.
Kod:
$noinit
$noramclear
$regfile "m32def.dat"
$crystal = 16000000
Const Fclk = 400000000
Const Fvfo = 20000000
Dim Pom As Double
Dim Pom2 As Double
Dim Ftw As Dword
Pom = &H100000000
Pom2 = Fvfo
Pom = Pom * Pom2
Pom2 = Fclk
Pom = Pom / Pom2
Ftw = Pom
End
Okazało się że Bascom wygenerował :
Kod: 1 276 (40+1 236)
Cykle: 2 917 (20+2897) - ~182ns
Wynik:
0x0CCCCCCD
W pierwszej chwili wynik mnie zaskoczył, ale jak dokładnie policzyłem wynik dokładny to 214 748 364,8 w zaokrągleniu 214748365 czyli 0x0CCCCCCD.