Code.RogerHub » math https://rogerhub.com/~r/code.rogerhub The programming blog at RogerHub Fri, 27 Mar 2015 23:04:04 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.2 How to tell if your system is big endian or little endian https://rogerhub.com/~r/code.rogerhub/terminal-fu/112/how-to-tell-if-your-system-is-big-endian-or-little-endian/ https://rogerhub.com/~r/code.rogerhub/terminal-fu/112/how-to-tell-if-your-system-is-big-endian-or-little-endian/#comments Tue, 26 Mar 2013 02:06:19 +0000 https://rogerhub.com/~r/code.rogerhub/?p=112 I was on MDN when I noticed that Chrome’s V8 (at least) was little-endian, meaning that a hexadecimal number you’d write as 0xCAFEBABE is actually stored as BE BA FE CA if you read the bytes off memory. It made me wonder how you could most easily determine if your system is little or big endian. I then came upon this gem:

echo -n I | od -to2 | head -n1 | cut -f2 -d" " | cut -c6

I’ll go through it part by part:

  • echo -n I – You’re already familiar with echo. The -n switch just suppresses the newline \n character that, by default, follows the output. This part just prints the letter I.
  • od -to2 – If you look at man ascii, you’ll notice that in the 7-bit octal range (00 to 0177), the letter I is 0111, which has the convenient property of being all 1’s. od is a program that lets you inspect, in human-readable format, what may or may not be printable characters. The -to2 switch tells it to print 2 bytes in octal. (The -to1 switch would not work because both little-endian and big-endian machines would indistinguishably print 111.) Little-endian machines will give you 0000000 000111 while big-endian machines will give you 0000000 111000. Great! Let’s simplify this result down a bit.
  • head -n1 – Here’s an easy one. We’re just grabbing the first line of stdin and spitting it back out.
  • cut -f2 -d" " – Another good one to know. Cut is string.split(). The -f2 switch tells it that the second field is desired, and the -d" " switch gives it a single space character as a delimeter.
  • cut -c6 – Finally, here’s another cut. This one just grabs the 6th character. The 4th or the 5th would also suffice.

You could take this one-liner a step further and add conditional printing of “big endian” or “little endian”, but by point #2, it’s pretty much there.

]]>
https://rogerhub.com/~r/code.rogerhub/terminal-fu/112/how-to-tell-if-your-system-is-big-endian-or-little-endian/feed/ 0
A better better calculator with bc https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/ https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/#comments Mon, 25 Mar 2013 20:55:51 +0000 https://rogerhub.com/~r/code.rogerhub/?p=90 GNU/bc is a command-line calculator for linux. It does variables [a-z0-9_]+ and +-*/^ and basic math, all through the terminal, and while it’s somewhat useful by default, it can be made to be a lot better. Reading man bc, you see that the program reads an environmental variable, BC_ENV_ARGS, which refers to a list of command line arguments implicitly appended to every invocation of bc. Quoting the source, those files “typically contain function definitions for functions the user wants defined every time bc is run”.

alias bc='bc -l'

First off, you’ll want to alias bc with the -l command line argument, which loads a bunch of math functions including the following:

s(x) Sine
c(x) Cosine
a(x) Arctangent
l(x) Natural logarithm
e(x) Exponential function
j(n, x) Bessel function

They clearly defined this minimal set with the expectation that you’d extend them, so of course, I did. In ~/.bashrc, I exportd BC_ENV_ARGS=~/.bcrc, and started the following in ~/.bcrc:

/* Config for bc */
scale=39

Scale is a special variable in bc. It determines the number of significant figures that bc will carry in its calculations, and 39 worked well for me. Then I defined some physical constants in the form of k_[a-z]+:

print "\n"
print "Usage: k_[?] with one of: c, g, atm (atmospheric), h, hbar, mu,\n"
print "       ep(silon), e (elementary charge), coulomb, me (electron),\n"
print "       mp, n (avogadro's), b (boltzmann), r (gas), si(gma)\n\n"

k_c = 299792458 /* Speed of Light */
k_g = 6.67384 * 10^-11 /* Universal Gravitation */
k_atm = 100325 /* Atmospheric pressure */
k_h = 6.62606957 * 10^-34 /* Planck's constant */
k_hbar = 1.054571726 * 10^-34 /* H Bar */
k_mu = 1.256637061 * 10^-6 /* Vacuum permeability */
k_ep = 8.854187817 * 10^-12 /* Vacuum permittivity */
k_epsilon = 8.854187817 * 10^-12 /* Vacuum permittivity */
k_e = 1.602176565 * 10^-19 /* Elementary charge */
k_coulomb = 8.987551787 * 10^9 /* Coulomb's constant */
k_me = 9.10938294 * 10^-31 /* Rest mass of an electron */
k_mp = 1.672621777 * 10^-27 /* Rest mass of a proton */
k_n = 6.02214129 * 10^23 /* Avogadro's number */
k_b = 1.3806488 * 10^-23 /* Boltzmann's constant */
k_r = 8.3144621 /* Ideal gas constant */
k_si = 5.670373 * 10^-8 /* Stefan-Boltzmann constant */
k_sigma = 5.670373 * 10^-8 /* Stefan-Boltzmann constant */

pi = 3.1415926535897932384626433832795028841968 /* pi */

And then these:

print "Usage: s(x) c(x) t(x) as(x) ac(x) at(x)\n"
print "       csc(x) sec(x) cot(x) e(x)\n\n"
define t(x) { return s(x)/c(x); }
define as(x) { return 2*a(x/(1+sqrt(1-x^2))); }
define ac(x) { return 2*a(sqrt(1-x^2)/(1+x)); }
define at(x) { return a(x); }
define csc(x) { return 1/s(x); }
define sec(x) { return 1/c(x); }
define cot(x) { return c(x)/s(x); }

I printed the default mathlib functions in the Usage for completeness. Stuff like sqrt() works too. I use bc primarily for physics homework, since built-in GUI calculators often have better base-conversion and visualization abilities for programming.

]]>
https://rogerhub.com/~r/code.rogerhub/infrastructure/90/a-better-better-calculator-with-bc/feed/ 0