diff --git a/ebpfcat/arraymap.py b/ebpfcat/arraymap.py
index 05fadec4644753e0306480a241fc69a3a12b7334..288869d6fa32d4d977a3680e08ed7b76b238ef11 100644
--- a/ebpfcat/arraymap.py
+++ b/ebpfcat/arraymap.py
@@ -29,7 +29,7 @@ class ArrayGlobalVarDesc(MemoryDesc):
     def __init__(self, map, fmt):
         self.map = map
         self.fmt = fmt
-        self.fixed = fmt == "f"
+        self.fixed = fmt == "x"
 
     def fmt_addr(self, ebpf):
         return self.fmt, ebpf.__dict__[self.name]
@@ -43,7 +43,7 @@ class ArrayGlobalVarDesc(MemoryDesc):
         if instance.ebpf.loaded:
             fmt, addr = self.fmt_addr(instance)
             data = instance.ebpf.__dict__[self.map.name].data
-            if fmt == "f":
+            if fmt == "x":
                 return unpack_from("q", data, addr)[0] / Expression.FIXED_BASE
             else:
                 ret = unpack_from(fmt, data, addr)
@@ -57,7 +57,7 @@ class ArrayGlobalVarDesc(MemoryDesc):
     def __set__(self, instance, value):
         if instance.ebpf.loaded:
             fmt, addr = self.fmt_addr(instance)
-            if fmt == "f":
+            if fmt == "x":
                 fmt = "q"
                 value = int(value * Expression.FIXED_BASE)
             if not isinstance(value, tuple):
@@ -87,7 +87,7 @@ class ArrayMap(Map):
         for prog in chain([ebpf], ebpf.subprograms):
             for k, v in prog.__class__.__dict__.items():
                 if isinstance(v, ArrayGlobalVarDesc):
-                    collection.append((8 if v.fmt == "f" else calcsize(v.fmt),
+                    collection.append((8 if v.fmt == "x" else calcsize(v.fmt),
                                        prog, k))
         collection.sort(key=lambda t: t[0], reverse=True)
         position = 0
diff --git a/ebpfcat/ebpf.py b/ebpfcat/ebpf.py
index 0750830d9b90e069099c75fdd956a368bc8555df..c21bd3e651f777cb0070913e150f7555fe40f8db 100644
--- a/ebpfcat/ebpf.py
+++ b/ebpfcat/ebpf.py
@@ -870,7 +870,7 @@ class Memory(Expression):
     bits_to_opcode = {32: Opcode.W, 16: Opcode.H, 8: Opcode.B, 64: Opcode.DW}
     fmt_to_opcode = {'I': Opcode.W, 'H': Opcode.H, 'B': Opcode.B, 'Q': Opcode.DW,
                      'i': Opcode.W, 'h': Opcode.H, 'b': Opcode.B, 'q': Opcode.DW,
-                     'A': Opcode.W, 'f': Opcode.DW}
+                     'A': Opcode.W, 'x': Opcode.DW}
 
     def __init__(self, ebpf, fmt, address):
         self.ebpf = ebpf
@@ -922,7 +922,7 @@ class Memory(Expression):
 
     @property
     def fixed(self):
-        return isinstance(self.fmt, str) and self.fmt == "f"
+        return isinstance(self.fmt, str) and self.fmt == "x"
 
     def __invert__(self):
         if not isinstance(self.fmt, tuple) or self.fmt[1] != 1:
@@ -992,11 +992,11 @@ class MemoryDesc:
             ebpf.append(Opcode.ST + bits, self.base_register, 0,
                         addr, value)
             return
-        if self.fmt == "f" and not value.fixed:
+        if self.fmt == "x" and not value.fixed:
             value = value * Expression.FIXED_BASE
-        elif self.fmt != "f" and value.fixed:
+        elif self.fmt != "x" and value.fixed:
             value = value / Expression.FIXED_BASE
-        with value.calculate(None, isinstance(fmt, str) and fmt in 'qQf'
+        with value.calculate(None, isinstance(fmt, str) and fmt in 'qQx'
                             ) as (src, _):
             ebpf.append(opcode + bits, self.base_register, src, addr, 0)
 
@@ -1007,10 +1007,12 @@ class LocalVar(MemoryDesc):
 
     def __init__(self, fmt='I'):
         self.fmt = fmt
-        self.fixed = fmt == "f"
+        self.fixed = fmt == "x"
 
     def __set_name__(self, owner, name):
-        if isinstance(self.fmt, str):
+        if self.fmt == "x":
+            size = 8
+        elif isinstance(self.fmt, str):
             size = calcsize(self.fmt)
         else:  # this is to support bit addressing, mostly for testing
             size = 1
@@ -1041,7 +1043,7 @@ class MemoryMap:
                 offset = 0
             if isinstance(value, IAdd):
                 value = value.value
-                if self.fmt == "f":
+                if self.fmt == "x":
                     value = int(value * self.FIXED_BASE)
                 if not isinstance(value, Expression):
                     with self.ebpf.get_free_register(None) as src:
@@ -1054,7 +1056,7 @@ class MemoryMap:
             elif isinstance(value, Expression):
                 opcode = Opcode.STX
             else:
-                if self.fmt == "f":
+                if self.fmt == "x":
                     value = int(value * self.FIXED_BASE)
                 self.ebpf.append(Opcode.ST + Memory.fmt_to_opcode[self.fmt],
                                  dst, 0, offset, value)
@@ -1236,13 +1238,13 @@ class EBPF:
         self.mh = MemoryMap(self, "h")
         self.mi = MemoryMap(self, "i")
         self.mq = MemoryMap(self, "q")
-        self.mf = MemoryMap(self, "f")
+        self.mx = MemoryMap(self, "x")
 
         self.r = RegisterArray(self, True, False)
         self.sr = RegisterArray(self, True, True)
         self.w = RegisterArray(self, False, False)
         self.sw = RegisterArray(self, False, True)
-        self.f = RegisterArray(self, True, True, True)
+        self.x = RegisterArray(self, True, True, True)
 
         self.owners = {1, 10}
 
@@ -1367,7 +1369,7 @@ class EBPF:
     stmp = TemporaryDesc(None, "sr")
     wtmp = TemporaryDesc(None, "w")
     swtmp = TemporaryDesc(None, "sw")
-    ftmp = TemporaryDesc(None, "f")
+    xtmp = TemporaryDesc(None, "x")
 
 
 for i in range(11):
@@ -1383,7 +1385,7 @@ for i in range(10):
     setattr(EBPF, f"sw{i}", RegisterDesc(i, "sw"))
 
 for i in range(10):
-    setattr(EBPF, f"f{i}", RegisterDesc(i, "f"))
+    setattr(EBPF, f"x{i}", RegisterDesc(i, "x"))
 
 
 class SubProgram:
diff --git a/ebpfcat/ebpf.rst b/ebpfcat/ebpf.rst
index 1f107f9b1f8e41a607374ba296fbd4859f9a4d4d..cfc68387f5ea54382d3599fc7ccd2f8a065f097e 100644
--- a/ebpfcat/ebpf.rst
+++ b/ebpfcat/ebpf.rst
@@ -68,9 +68,9 @@ we cannot use a Python ``if`` statement, as then the code actually does not
 get executed, so no code would be generated. So we replace ``if`` statements
 by Python ``with`` statements like so::
 
-    with self.some_variable > 6 as cond:
+    with self.some_variable > 6 as Else:
         do_someting
-    with cond.Else():
+    with Else:
         do_something_else
 
 certainly an ``Else`` statement may be omitted if not needed.
@@ -144,16 +144,33 @@ variables at the same time. So concurrent access may lead to problems. An
 exception is the in-place addition operator `+=`, which works under a lock,
 but only if the variable is of 4 or 8 bytes size.
 
-Otherwise variables may be declared in all sizes. Additionally, one can mark
-which variables are supposed to be written from user space to the EBPF,
-as opposed to just being read. The declaration is like so::
+Otherwise variables may be declared in all sizes. The declaration is like so::
 
    class MyProgram(EBPF):
        array_map = ArrayMap()
-       a_read_var = array_map.globalVar("B")  # one byte read-only variable
-       a_write_var = array_map.globalVar("i", write=True)  # read-write integer
-
-the array map has methods to access the variables:
-
-.. autoclass:: ebpfcat.arraymap.ArrayMapAccess
-   :members:
+       a_byte_variable = array_map.globalVar("B")
+       an_integer_variable = array_map.globalVar("i")
+
+those variables can be accessed both from within the ebpf program, as from
+outside. Both sides are actually accessing the same memory, so be aware of
+race conditions.
+
+Fixed-point arithmetic
+~~~~~~~~~~~~~~~~~~~~~~
+
+as a bonus beyond standard ebpf, we support fixed-point values as a type `x`.
+Within ebpf they are calculated as per-10000, so a 0.2 is represented as
+20000. From outside, the variables seem to be doubles. Vaguely following
+Python, all true divisions `/` result in a fixed-point result, while all
+floor divisions `//` result in a standard integer. Some examples:
+
+    class FixedPoint(EPBF):
+        array_map = ArrayMap()
+        fixed_var = array_map.globalVar("x")  # declare a fixed-point variable
+        normal_var = array_map.globalVar("i")
+
+        def program(self):
+            self.fixed_var = 3.5  # automatically converted to fixed
+            self.normal_var = self.fixed_var  # automatically truncated
+            self.fixed_var = self.normal_var / 5  # keep decimals
+            self.fixed_var = self.normal_var // 5  # floor division
diff --git a/ebpfcat/ebpf_test.py b/ebpfcat/ebpf_test.py
index 0ffdac5d947384d2c6304752c651bc6fe41d158e..c61bb959b4ec94b3d99f0f7bca470aeeaa9bf53b 100644
--- a/ebpfcat/ebpf_test.py
+++ b/ebpfcat/ebpf_test.py
@@ -165,32 +165,32 @@ class Tests(TestCase):
     def test_fixed(self):
         e = EBPF()
         e.owners = {0, 1, 2, 3, 4, 5, 6}
-        e.f1 = e.r2 + 3
-        e.f3 = e.r4 + 3.5
-        e.f5 = e.f6 + 3
-        e.r1 = e.r2 + e.f3
-        e.f4 = e.f5 + e.f6
-        e.r1 = 2 - e.f2
+        e.x1 = e.r2 + 3
+        e.x3 = e.r4 + 3.5
+        e.x5 = e.x6 + 3
+        e.r1 = e.r2 + e.x3
+        e.x4 = e.x5 + e.x6
+        e.r1 = 2 - e.x2
         e.r3 = 3.4 - e.r4
-        e.r5 = e.f6 % 4
-
-        e.f1 = e.r2 * 3
-        e.f3 = e.r4 * 3.5
-        e.f5 = e.f6 * 3
-        e.r1 = e.r2 * e.f3
-        e.f4 = e.f5 * e.f6
-
-        e.f1 = e.r2 / 3
-        e.f3 = e.r4 / 3.5
-        e.f5 = e.f6 / 3
-        e.r1 = e.r2 / e.f3
-        e.f4 = e.f5 / e.f6
-
-        e.f1 = e.r2 // 3
-        e.f3 = e.r4 // 3.5
-        e.f5 = e.f6 // 3
-        e.r1 = e.r2 // e.f3
-        e.f4 = e.f5 // e.f6
+        e.r5 = e.x6 % 4
+
+        e.x1 = e.r2 * 3
+        e.x3 = e.r4 * 3.5
+        e.x5 = e.x6 * 3
+        e.r1 = e.r2 * e.x3
+        e.x4 = e.x5 * e.x6
+
+        e.x1 = e.r2 / 3
+        e.x3 = e.r4 / 3.5
+        e.x5 = e.x6 / 3
+        e.r1 = e.r2 / e.x3
+        e.x4 = e.x5 / e.x6
+
+        e.x1 = e.r2 // 3
+        e.x3 = e.r4 // 3.5
+        e.x5 = e.x6 // 3
+        e.r1 = e.r2 // e.x3
+        e.x4 = e.x5 // e.x6
 
         self.maxDiff = None
         self.assertEqual(e.opcodes, [
@@ -278,14 +278,14 @@ class Tests(TestCase):
             b = LocalVar('H')
             c = LocalVar('i')
             d = LocalVar('Q')
-            lf = LocalVar('f')
+            lx = LocalVar('x')
 
         e = Local(ProgType.XDP, "GPL")
         e.a = 5
         e.b = e.c >> 3
         e.d = e.r1
-        e.lf = 7
-        e.b = e.f1
+        e.lx = 7
+        e.b = e.x1
 
         self.assertEqual(e.opcodes, [
             Instruction(opcode=O.B+O.ST, dst=10, src=0, off=-1, imm=5),
@@ -293,7 +293,7 @@ class Tests(TestCase):
             Instruction(opcode=O.ARSH, dst=0, src=0, off=0, imm=3),
             Instruction(opcode=O.REG+O.STX, dst=10, src=0, off=-4, imm=0),
             Instruction(opcode=O.DW+O.STX, dst=10, src=1, off=-16, imm=0),
-            Instruction(opcode=O.DW+O.ST, dst=10, src=0, off=-20, imm=700000),
+            Instruction(opcode=O.DW+O.ST, dst=10, src=0, off=-24, imm=700000),
             Instruction(opcode=O.LONG+O.REG+O.MOV, dst=0, src=1, off=0, imm=0),
             Instruction(opcode=O.DIV, dst=0, src=0, off=0, imm=100000),
             Instruction(opcode=O.REG+O.STX, dst=10, src=0, off=-4, imm=0),
@@ -504,13 +504,13 @@ class Tests(TestCase):
             e.r5 = 7
         with Else:
             e.r7 = 8
-        with e.f4 > 3:
+        with e.x4 > 3:
             pass
-        with 3 > e.f4:
+        with 3 > e.x4:
             pass
         with e.r4 > 3.5:
             pass
-        with e.f4 > e.f2:
+        with e.x4 > e.x2:
             pass
         self.assertEqual(e.opcodes, [
              Instruction(opcode=0xb5, dst=2, src=0, off=2, imm=3),
@@ -735,7 +735,7 @@ class Tests(TestCase):
     def test_absolute(self):
         e = EBPF()
         e.r7 = abs(e.r1)
-        e.f3 = abs(e.f1)
+        e.x3 = abs(e.x1)
         self.assertEqual(e.opcodes, [
             Instruction(opcode=O.LONG+O.REG+O.MOV, dst=7, src=1, off=0, imm=0),
             Instruction(opcode=O.JSGE, dst=7, src=0, off=1, imm=0),
@@ -850,10 +850,10 @@ class Tests(TestCase):
                 e.r7 = e.tmp
             e.tmp = 2
             e.r3 = e.tmp
-        with e.ftmp:
-            e.ftmp = 3
-            e.r3 = e.ftmp
-            e.ftmp = e.r3 * 3.5
+        with e.xtmp:
+            e.xtmp = 3
+            e.r3 = e.xtmp
+            e.xtmp = e.r3 * 3.5
         self.assertEqual(e.opcodes, [
             Instruction(opcode=O.MOV+O.LONG, dst=0, src=0, off=0, imm=7),
             Instruction(opcode=O.MOV+O.LONG, dst=2, src=0, off=0, imm=3),
@@ -927,7 +927,7 @@ class KernelTests(TestCase):
         class Sub(SubProgram):
             br = Global.map.globalVar()
             bw = Global.map.globalVar("h")
-            bf = Global.map.globalVar("f")
+            bf = Global.map.globalVar("x")
 
             def program(self):
                 self.bw = 4
diff --git a/ebpfcat/hashmap.py b/ebpfcat/hashmap.py
index 8e5e61c86ab792634dff95218c3a11c8ef34e3b6..126f0c7746d91b00218b0bfa19baf48c2e852428 100644
--- a/ebpfcat/hashmap.py
+++ b/ebpfcat/hashmap.py
@@ -28,7 +28,7 @@ class HashGlobalVar(Expression):
         self.count = count
         self.fmt = fmt
         self.signed = fmt.islower()
-        self.fixed = fmt == "f"
+        self.fixed = fmt == "x"
 
     @contextmanager
     def get_address(self, dst, long, force=False):