Those numbers make sense.
PulseIn measures the duration of the high or low part of the pulse, not the full iteration of the signal. A 100Khz square wave with a 50% duty cycle will be high or low for 5 microseconds... 4? It rounded down. 4970 at 100 Hz? that's 9940 micro seconds for the full cycle. That's close.
The last 2 are way off, and probably because println() is trying to format it and number is too big.
try:
char text[20];
sprintf(text,"%lu",duration);
Serial.println(text);
At least I think that will work... I haven't used Serial.println() in a while because it's a blocking call.