fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: Zähle...
|
shiro schrieb: Jetzt fehlt nur noch awk als "richtige" Programmiersprache:
Das kann man auch noch wesentlich kürzer schreiben, aber ich wollte die Definition von fireworker72's Post hier verwenden.
echo -e "1901\n9901" | awk '{d=strtonum("0X"$0);print (1-2*rshift(d,15))*and(d,0x7ff)*0.01*2^and(rshift(d,11),0xf)}'
20.56
-20.56
Wie wäre da eigentlich der umgekehrte weg mit awk von Dec nach Hex?
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 583
|
Wie wäre da eigentlich der umgekehrte weg mit awk von Dec nach Hex?
Diese Aufgabe ist etwas komplizierter, da man ja eine möglichst aussagefähige Mantisse haben möchte. Daher ist der Exponent zu suchen, bei dem die Mantisse beim rechts-shift das erste mal in Bit-Position 0 eine 1 hat und dabei bei der Mantisse keine Overflow (<0x800) aufweist. Ich habe daher das folgende bash script beigefügt, das zwei bash Funktionen aufweist um die Hex Werte in float und umgekehrt zu wandeln:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | #!/bin/bash
function hex2float(){
awk -v h="$1" 'BEGIN{d=strtonum("0X"h);print (1-2*rshift(d,15))*and(d,0x7ff)*0.01*2^and(rshift(d,11),0xf)}'
}
function float2hex(){
awk -v r="$1" 'BEGIN{if(r<0){v=1;r=-r}else{v=0};z=int(r*100);for(e=0;e<16;e++){if(z<0x800 && and(z,1)==1){break}else{z=rshift(z,1)}}
printf "%04x\n",or(lshift(v,15),or(lshift(e,11),and(z,0x7ff)))}'
}
echo "nun als function:"
hex2float 9901
hexwert="1901"
realwert=$(hex2float $hexwert)
echo "realwert=$realwert; hexwert=$hexwert"
echo "und nun zurück"
float2hex -20.56
rwert="20.56"
x=$(float2hex $rwert)
echo "rwert=$rwert, ergebnis=$x"
|
PS: Ich hatte im Code-Block das Syntax Highlighting vergessen. Übrigens ist über die geringe Zahl der Bits bei der Mantisse die signifikante Anzahl der Dezimalstellen begrenzt (also nicht wundern, das gilt praktisch für jede Float Darstellung).
|
fireworker72
(Themenstarter)
Anmeldungsdatum: 11. März 2017
Beiträge: 59
|
Danke Das sollte jetzt auf das umrechnen oder? “2-Octet Float Value” FloatValue = (0,01*M)*2(E)
E = [0 … 15]
M = [-2 048 … 2 047], two’s complement notation
For all Datapoint Types 9.xxx, the encoded value 7FFFh shall always be used to denote invalid data.
Range:
[-671 088,64 … 670 433,28]
PDT:
PDT_KNX_FLOAT
|
shiro
Anmeldungsdatum: 20. Juli 2020
Beiträge: 583
|
Das sollte jetzt auf das umrechnen oder? “2-Octet Float Value”
Ja, so sehe ich das auch so. Der Wertebereich stimmt auch.
$ float2hex -671088,64
ffff
$ hex2float ffff
-670761
Die Differenz zwischen den beiden Werten liegt an der geringen Anzahl Bits der Mantisse. Der Exponent von 2^15 verstärkt diese "Ungenauigkeit" wie oben beschrieben.
|