DOSBox has two FPU (floating point unit) emulators. One is used by default when running DOSBox on x86 hardware. It uses actual x86 FPU instructions, and it should provide the full 80-bit long double precision. The other one does not require x86 hardware, and uses standard doubles. That means it does not give the full precision one would expect from a real FPU.
In OLE2DISP.DLL 2.3.3027.1, there is a check for precision loss. The code loads a 64-bit integer using FILD, stores a 10 byte BCD number using FBSTP, and then tests the last four digits. If the digits aren't correct, it pops another value, causing the stack underflow.
Normally, this would cause an FPU underflow exception to be noticed by Windows, but DOSBox doesn't pass on those exceptions and instead quits emulation. This is of course an inaccuracy in CPU emulation. DOSBox isn't a very good general purpose x86 CPU emulator, partly because it is a hybrid of an operating system and CPU emulator. DOSBox is designed for running old games and good at that, but not general purpose emulation. I'm tempted to try to port Bochs to make a better general purpose emulator available. For now, I simply disabled the FPU stack underflow check, because that allows many Windows 3.x apps to work.
Here is an image of execution diverging after the test. I used this to find the location where the test was. Note that due to relocations, searching for this in files can be tricky. The image at the right is from the very helpful http://ref.x86asm.net/coder32.html table.
Finally, here's some x86 assembler code performing this test. This fails in DOSBox 0.74 in 64 bit Linux, but works in my SDL 2 branch, which is based on r3869. This is probably due to r3851. I hadn't written a DOS assembler program in so long, so this was fun:
; FPU test like OLE2DISP.DLL 2.3.3027.1
; Build using: nasm ole2disp.asm -o ole2disp.com
segment code
org 100h
; This is the test
wait
fild qword [input]
wait
fbstp tword [output]
nop
wait
mov dx, header
mov ah, 9
int 21h
; This displays output
mov cx, 10
mov si, output+9
std
outloop:
mov al, [si]
shr al, 1
shr al, 1
shr al, 1
shr al, 1
call outdig
lodsb
call outdig
loop outloop
int 20h
; Display a single hex digit.
outdig:
xor ah, ah
and al, 0fh
mov bx, hex
add bx, ax
mov dl, byte [bx]
mov ah, 2
int 21h
ret
segment data
input: times 6 db 0
db 0dfh, 00dh
output: times 10 db 0
hex: db "0123456789ABCDEF"
header: db "FILD, FBSTP FPU test like OLE2DISP.DLL 2.3.3027.1", 13, 10
db "00999517642299539456 is correct result. "
db "Last 4 digits of following must match:", 13, 10, '$'