# HG changeset patch # User David Bateman # Date 1206490966 14400 # Node ID b2fbb393a072bd7feb019fa3c9756c465f8fba9c # Parent 2df457529cfacdb4ffc2a030e54869ccef31253b Add the num2hex and hex2num functions diff --git a/doc/ChangeLog b/doc/ChangeLog --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2008-03-25 David Bateman + + * interpreter/strings.txi: Document hex2num, num2hex. + 2008-03-21 David Bateman * interpreter/sparse.txi: Document amd function. diff --git a/doc/interpreter/strings.txi b/doc/interpreter/strings.txi --- a/doc/interpreter/strings.txi +++ b/doc/interpreter/strings.txi @@ -297,6 +297,10 @@ @DOCSTRING(base2dec) +@DOCSTRING(num2hex) + +@DOCSTRING(hex2num) + @DOCSTRING(str2double) @DOCSTRING(strjust) diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2008-03-25 David Bateman + + * DLD-FUNCTIONS/hex2num.cc: New function + * Makefile.in (DLD_XSRC): Add hex2num.cc. + 2008-03-25 Jaroslav Hajek * mappers.cc (Fexpm1, Flog1p): New functions. diff --git a/src/DLD-FUNCTIONS/hex2num.cc b/src/DLD-FUNCTIONS/hex2num.cc new file mode 100644 --- /dev/null +++ b/src/DLD-FUNCTIONS/hex2num.cc @@ -0,0 +1,183 @@ +/* + +Copyright (C) 2008 David Bateman + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "defun-dld.h" +#include "error.h" +#include "gripes.h" +#include "oct-obj.h" +#include "utils.h" + +DEFUN_DLD (hex2num, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{n} =} hex2num (@var{s})\n\ +Typecast the 16 character hexadecimal character matrix to an IEEE 754\n\ +double precision number. If fewer than 16 characters are given the\n\ +strings are right padded with '0' characters.\n\ +\n\ +Given a string matrix, @code{hex2num} treats each row as a separate\n\ +number.\n\ +\n\ +@example\n\ +hex2num ([\"4005bf0a8b145769\";\"4024000000000000\"])\n\ +@result{} [2.7183; 10.000]\n\ +@end example\n\ +@seealso{num2hex, hex2dec, dec2hex}\n\ +@end deftypefn") +{ + int nargin = args.length (); + octave_value retval; + + if (nargin != 1) + print_usage (); + else + { + const charMatrix cmat = args(0).char_matrix_value (); + + if (cmat.columns () > 16) + error ("hex2num: expecting no more than a 16 character string"); + else if (! error_state) + { + octave_idx_type nr = cmat.rows (); + octave_idx_type nc = cmat.columns (); + ColumnVector m (nr); + + for (octave_idx_type i = 0; i < nr; i++) + { + uint64_t num = 0; + for (octave_idx_type j = 0; j < nc; j++) + { + unsigned char ch = cmat.elem (i, j); + + if (isxdigit (ch)) + { + num <<= 4; + if (ch >= 'a') + num += static_cast (ch - 'a' + 10); + else if (ch >= 'A') + num += static_cast (ch - 'A' + 10); + else + num += static_cast (ch - '0'); + } + else + { + error ("hex2num: illegal character found in string"); + break; + } + } + + if (error_state) + break; + else + { + if (nc < 16) + num <<= (16 - nc) * 4; + + m (i) = *reinterpret_cast(&num); + + } + } + + if (! error_state) + retval = m; + } + } + + return retval; +} + +/* + +%!assert (hex2num(['c00';'bff';'000';'3ff';'400']),[-2:2]') + + */ + + + +DEFUN_DLD (num2hex, args, , + "-*- texinfo -*-\n\ +@deftypefn {Loadable Function} {@var{s} =} num2hex (@var{n})\n\ +Typecast a double precision number or vector to a 16 character hexadecimal\n\ +string of the IEEE 754 representation of the number. For example\n\ +\n\ +@example\n\ +num2hex ([-1, 1, e, Inf, NaN, NA]);\n\ +@result{} \"bff0000000000000\n\ + 3ff0000000000000\n\ + 4005bf0a8b145769\n\ + 7ff0000000000000\n\ + fff8000000000000\n\ + 7ff00000000007a2\"\n\ +@end example\n\ +@seealso{hex2num, hex2dec, dec2hex}\n\ +@end deftypefn") +{ + int nargin = args.length (); + octave_value retval; + + if (nargin != 1) + print_usage (); + else + { + const ColumnVector v (args(0).vector_value ()); + + if (! error_state) + { + octave_idx_type nr = v.length (); + charMatrix m (nr, 16); + const double *pv = v.fortran_vec (); + + for (octave_idx_type i = 0; i < nr; i++) + { + const uint64_t num = *reinterpret_cast (pv++); + for (octave_idx_type j = 0; j < 16; j++) + { + unsigned char ch = + static_cast (num >> ((15 - j) * 4) & 0xF); + if (ch >= 10) + ch += 'a' - 10; + else + ch += '0'; + + m.elem (i, j) = ch; + } + } + + retval = octave_value (m, true); + } + } + + return retval; +} + +/* + +%!assert (num2hex (-2:2),['c000000000000000';'bff0000000000000';'0000000000000000';'3ff0000000000000';'4000000000000000']) + + */ + + diff --git a/src/Makefile.in b/src/Makefile.in --- a/src/Makefile.in +++ b/src/Makefile.in @@ -67,7 +67,7 @@ dasrt.cc dassl.cc det.cc dispatch.cc dlmread.cc dmperm.cc eig.cc \ expm.cc fft.cc fft2.cc fftn.cc fftw.cc filter.cc find.cc fsolve.cc \ gammainc.cc gcd.cc getgrent.cc getpwent.cc getrusage.cc \ - givens.cc hess.cc inv.cc kron.cc lsode.cc \ + givens.cc hess.cc hex2num.cc inv.cc kron.cc lsode.cc \ lu.cc luinc.cc matrix_type.cc md5sum.cc minmax.cc pinv.cc qr.cc \ quad.cc qz.cc rand.cc regexp.cc schur.cc sparse.cc \ spparms.cc sqrtm.cc svd.cc syl.cc symrcm.cc symbfact.cc \