Search code examples
command-linefloating-pointbinaryfilesraw-data

Subtract raw floating-point files elementwise, with a script?


I have two files which are raw sequences of little-endian 32-bit floating-point values (with no crazy values like infinity, NaN, denormals etc.), and I want to produce their elementwise difference in a third file.

Now, I can write a small utility to do this with relative efficiently in pretty much any compiled language, but I was wondering if I could achieve the same more easily with a short script using common tools. My intuition says "no", since it's pretty "non-textual" work, but maybe I'm wrong.


Solution

  • A quick perl script that'll do it (Takes the two files as command line arguments, writes to standard output):

    #!/usr/bin/env perl
    use warnings;
    use strict;
    
    open my $file1, "<:raw", $ARGV[0] or die "Unable to open $ARGV[0]: $!\n";
    open my $file2, "<:raw", $ARGV[1] or die "Unable to open $ARGV[1]: $!\n";
    binmode STDOUT, ":raw";
    
    while (read($file1, my $s1, 4) == 4 && read($file2, my $s2, 4) == 4) {
        my $f1 = unpack "f<", $s1;
        my $f2 = unpack "f<", $s2;
        print pack("f<", $f1 - $f2);
    }
    

    The key here is pack and unpack's "f<" format to work with explicitly little-endian single precision floats (In the host systems' native format, normally IEEE754 on most typical hardware).