summaryrefslogtreecommitdiff
path: root/2/homework/2.90.c
diff options
context:
space:
mode:
authorMike Vink <mike@pionative.com>2024-05-22 08:49:29 +0200
committerMike Vink <mike@pionative.com>2024-05-22 08:49:29 +0200
commit51169f5f9ab178a4ddfe9dac461405a71c9c0f94 (patch)
tree0b6bb0c6c31ee27361b28e2c5993f362c1cc95e2 /2/homework/2.90.c
parent77f19e4a89d8dec97930c5e237139734c5fb3365 (diff)
organise
Diffstat (limited to '2/homework/2.90.c')
-rw-r--r--2/homework/2.90.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/2/homework/2.90.c b/2/homework/2.90.c
new file mode 100644
index 0000000..8eefec3
--- /dev/null
+++ b/2/homework/2.90.c
@@ -0,0 +1,112 @@
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <limits.h>
+#include <math.h>
+#include "../code/data/show-bytes.c"
+
+
+float my_u2f(unsigned int my_u) {
+ assert(sizeof(unsigned int) == sizeof(float));
+ union {
+ unsigned int u;
+ float f;
+ } my_union;
+ /* Apparently you cannot print the bytes of a float directly? like this printf("%x\n", f); */
+ my_union.u = my_u;
+ return my_union.f;
+}
+
+float fpwr2(int x)
+{
+ /* Result exponent and fraction */
+ unsigned exp, frac;
+ unsigned u;
+
+ int k = 8;
+ int n = 23;
+
+ int bias = (1<<(k-1))-1;
+ int max_e = ((1<<k) - 2) - bias;
+
+ if (x < 1-bias-n) {
+ /* Too small. Return 0.0 */
+ exp = 0;
+ frac = 0;
+ } else if (x < 1-bias) {
+ /* Denormalized, [(1-bias-n), (1-bias)] [-139, -126] */
+ exp = 0;
+ frac = 1<<(x+1-bias-n);
+ } else if (x<=max_e) {
+ /* Normalized */
+ exp = x+bias;
+ frac = 0;
+ } else {
+ /* Too big. Return +oo */
+ exp = (1<<8)-1;
+ frac = 0;
+ }
+
+ /* Pack exp and frac into 32 bits */
+ u = (exp << 23) | frac;
+ /* Return as float */
+ return my_u2f(u);
+}
+
+
+int main(void) {
+
+ /* 2.90 */
+ printf("%f\n", fpwr2(-1)); /* 65536 */
+ printf("%f\n", fpwr2(16)); /* 65536 */
+ printf("%f\n", fpwr2(15)); /* 32768 */
+ printf("%f\n", fpwr2(14)); /* 16384 */
+ printf("%f\n", fpwr2(13)); /* 8192 */
+ printf("%f\n", fpwr2(12)); /* 4096 */
+ printf("%f\n", fpwr2(11)); /* 2048 */
+ printf("%f\n", fpwr2(10)); /* 1024 */
+ printf("%f\n", fpwr2(128));
+ return 0;
+
+ /* 2.91 */
+ printf("%x\n", 0b01000000010010010000111111011011);
+ /*
+ 0 10000000 10010010000111111011011
+ E = 128-127 = 1
+ M = 1 + f
+ f = (2^22+2^19+2^16+2^11+2^10+2^9+2^8+2^7+2^6+2^4+2^3+2^1+2^0)/2^23
+ V = (2^E)(M)
+
+ 13176795/4194304
+
+ 22/7 = 2(1+f)
+ 11/7 = (1+f)
+ 4/7 = f
+
+ n = 0.yyy = f
+ n = Y/((1<<k) - 1)
+ n = 4/((1<<3) - 1)
+ 0 10000000 [100]+
+ */
+ show_float(22.0f/7.0f);
+ printf("%b\n", 0x40492492);
+ /* so we have 22/7
+ 0 10000000 10010010010010010010010
+ and the approx
+ 0 10000000 10010010000111111011011
+ at the 9th position the values diverge
+ */
+ return 0;
+
+ /* 2.90 */
+ printf("%f\n", fpwr2(-1)); /* 65536 */
+ printf("%f\n", fpwr2(16)); /* 65536 */
+ printf("%f\n", fpwr2(15)); /* 32768 */
+ printf("%f\n", fpwr2(14)); /* 16384 */
+ printf("%f\n", fpwr2(13)); /* 8192 */
+ printf("%f\n", fpwr2(12)); /* 4096 */
+ printf("%f\n", fpwr2(11)); /* 2048 */
+ printf("%f\n", fpwr2(10)); /* 1024 */
+ printf("%f\n", fpwr2(128));
+ return 0;
+}