x87 Machine Code, 11 bytes
D9 EB
DA 31
D9 F2
DD D8
DA 09
C3
The above bytes of code define a function that calculates the area of a regular n-gon with an apothem of 1. It uses x87 FPU instructions (the classic floating-point unit on the x86 processors) to do this computation.
Following a standard x86 register-based calling convention (in this case, __fastcall
), the function's argument is a pointer to the integer, passed in the ECX
register. The function's result is a floating-point value, returned at the top of the x87 floating-point stack (register ST0
).
Try it online!
Ungolfed assembly mnemonics:
D9 EB fldpi ; load constant PI at top of FPU stack
DA 31 fidiv DWORD PTR [ecx] ; divide PI by integer input (loaded from pointer
; in ECX), leaving result at top of FPU stack
D9 F2 fptan ; compute tangent of value at top of FPU stack
DD D8 fstp st0 ; pop junk value (FPTAN pushes 1.0 onto stack)
DA 09 fimul DWORD PTR [ecx] ; multiply by integer input (again, loaded via ECX)
C3 ret ; return control to caller
As you can see, this is basically just a straightforward computation of the given formula,
result = n * tan(π / n)
Only a couple of interesting things bear pointing out:
- The x87 FPU has a dedicated instruction for loading the constant value PI (
FLDPI
). This was rarely used, even back in the day (and obviously much less so now), but it's shorter in size than embedding a constant into your binary and loading that.
- The x87 FPU instruction to calculate tangent,
FPTAN
, replaces the value of the input register (the top of the FPU stack) with the result, but also pushes a constant 1.0 onto the top of the FPU stack. This is done for backwards compatibility with the 8087 (I have no idea why this was done on the 8087; probably a bug). That means we need to pop this unneeded value off of the stack. The fastest and shortest way to do that is a simple FSTP st0
, like we use here. We could have also done a multiply-and-pop, since multiplying by 1.0 won't change the result, but this is also 2 bytes (so no win in code size), will probably execute more slowly, and may introduce unnecessary indeterminacy into the result.
Although a modern programmer or compiler would use the SSE (and later) instruction set, rather than the aging x87, this would require more code to implement, as there's no single instruction to compute a tangent in these newer ISAs.