GNU Units
gnu.org
gnu.org
I’m sure it’s popped up here before but here’s a link for those who haven’t come across it: https://www.ibiblio.org/harris/500milemail.html
e.g. units "sec $(echo $SECONDS)" "day;hr;min;sec"
EDIT: The commenter echoed, duckly.
Wouldn't the signal have to do a full round trip within the timeout of 3 ms, meaning it could not go beyond 580 / 2 = 290 miles?
Additionally, the connection from A to B is usually not a straight line, and at that time fiber lines were much less widespread. All these factors combines make it unlikely that even 200 miles could be reached...
> Well, to start with, it can't be three milliseconds, because that would only be for the outgoing packet to arrive at its destination. You have to get a response, too, before the timeout will be aborted. Shouldn't it be six milliseconds?
> Of course. This is one of the details I skipped in the story. It seemed irrelevant, and boring, so I left it out.
I don't understand, so it was in fact 6 ms?
> That three millisecond time doesn't make sense as the timeout for a connect() call.
> Yes, I know. And it wasn't the timeout, actually. In the story, I make it sound like it took all of ten minutes from being made aware of the 500-mile email limit and determining a 3 ms light-speed issue. In fact, this took several hours, and quite a bit of detective work. The point is, eventually I came up with that figure, ran units, and gagged on my latte. (I'm fairly certain it was a different latte from the one I started with.) So what, in particular, is your question about the 3 ms figure?
I love that every time this link gets posted to HN someone says it looks like a hoax.
You have: 25 C
You want: K
conformability error
25 A s
1 K
You have: 1 cup flour
Unknown unit 'flour'
I think I'll stick with Google. You have: 5K * 300kg * water_specificheat
You want: kWh
* 1.7433333
really easy to use.How much power could you obtain with a small water turbine if you had 10m of head and 1l/s ? Easy !
You have: 10m * 1kg/s * gravity
You want: W
* 98.0665586 units, 56 prefixes
You have: 50m * 1kg/s * gravity
unknown unit 'gravity'
how did you get gravity?
$ units
Currency exchange rates from FloatRates (USD base) on 2020-12-21
3677 units, 109 prefixes, 114 nonlinear units
You have: 10m * 1kg/s * gravity
You want: W
* 98.0665
/ 0.010197162
You have:
You lack some units and prefixes.EDIT: Figured it out, just had to brew install gnu-units
Sometimes I need to bust out stoichiometry-like unit-balancing in the middle of my code, and I want type enforcement that I’m getting the right units in the output! Sometimes I want to do a series of floating-point calculations, and I need to put error-bars on the result, and it’d be great if those were tracked for me in the form of a measurement ADT that tracked sig-figs. Etc.
My only guess for why there’s no libunits, is that it’d be a obtrusive black-box of operational non-guarantees if it was implemented in C, given that what Units does — if naively implemented — would be heavy on arbitrary memory allocations, and basically necessitate garbage collection.
It’d make much more sense for a libunits to exist as a C++-ish “template library” that takes an allocator as an argument; but that doesn’t really help anyone who wants to use any language other than C++ (as the template parameters can’t be exposed in the C wrapper code that other languages FFI to.)
(Before someone asks, you could get a limited kind of united-quantities — ones that can only represent “realistic” units — with a static per-qty bitfield representing the compiled-in units. But this wouldn’t really let you represent arbitrary unexpected “unit polynomial” qtys, e.g. m^5s^-3. This might seem fine, but sometimes intermediate quantities in formulae look like that, even though they work out to something sensible when everything is multiplied out.)
Even if there couldn’t be a single units library implementation, it’d at least make sense for there to be 1. a canonical libunits-data release (sort of like tzdata), that individual library impls could pull in; and 2. a high-level API spec or reference-impl of what a libunits library for a given language-runtime would look like (sort of like how every HLL has copied JodaTime’s datetime design.)
Ruby has (among others, I’m certain): https://github.com/olbrich/ruby-units
Julia: https://github.com/PainterQubits/Unitful.jl
Python: https://pint.readthedocs.io/en/0.6/
C++: https://github.com/nholthaus/units
etc.
And yes, it has always struck me as strange that date/time/calendar utilities are standard as canonical functionality shipped with language distributions, but units are not.
https://github.com/GhostWrench/pqm
Also, I open sourced just the unit database (in JSON format) for anyone interested in making their own version:
Assuming this is straightforward is as wrong as with calendars / time Systems.
Be conservative in what you send, be liberal in what you accept.
leap years, leap seconds, julian dates, pre-gregorian dates, years beyond 9999, yyyy-mm-dd vs d/m/y vs month day year vs ..., zero padding, 12 hour vs 24 hour, 32 bit time stamps, DOS time accurate to every two seconds, why does excel need the date time in a specific format, I dual boot between Windows10 and Linux and every-time I boot up Windows10 the first thing I need to do is adjust the date time, pico-second granularity, time zones, daylight savings time, ...
Today is Stability (4), Flint (Tijaax * Etznab)
It's a good day to: Spend time in reflection and introspection.
1) That is not what we are talking about
2) Sometimes you just need a stopwatch, timing applications _can_ be simple
I went to search through dang's comment history to see whether he's posted any statistics to make that "huge number of users" more precise, but instead I found this comment which explains it better than any statistics: https://news.ycombinator.com/item?id=18523361
Heck... I was going ask you to write it, but now I'm thinking this could be a fun weekend project.
I can see one function in that library:
bool convert(const char *from, const char *to, double input, double *output);
No need to make it more complex for starters. If you want to make an .hxx Boost-like class around it, that's outta my league!EDIT: markdown help
EDIT: added a status return instead of val return to check for conversion correctness (bool is newer C)
Spaces on both sides: const char * from
But also you are supposed to mark up code by indenting with four spaces, and then everything will be treated as verbatim text:
const char *from1. I don't know what I am looking at with the examples. I think that this is an interactive session with the program, but this is not clear. 2. It is also unclear how to start the program as the executable name is not specified. This and the former point could be addressed by including one of those gifs of an interactive session that are popular in GitHub readmes these days. Sure, they are a bit gimmicky, but still useful. 3. It is not clearly stated if this is an executable program or a library. I believe it is the former, but this is nowhere in the introduction. 4. Probably this is included with a number of package managers. If that is the case, instructions for installing via a package manager would be helpful, especially since the name is not particularly unique.
I guess they also allow you to passively view a sequence of stuff instead of having to actively scroll to move through the sequence. Maybe that feels easier to some people.
(1) Often, the speed is wrong. Either they play too fast to follow along or they play too slowly and time is wasted waiting for it to show me the part I care about (or loop back around).
It's hard to get the speed just right. And AFAIK browsers don't offer controls to adjust the speed, and even if they did, it would be tedious.
(2) Personally I find animations (especially rapid or looping ones) quite distracting when trying to read the rest of the page. My eye just keeps moving to the thing that's trying to grab my attention.
I usually try to work around that by scrolling so that the animation is out of view. So, I'll live, but it's not a good user experience. And again, (some?) browsers seem to offer no help, like a setting to always enable animation controls (play/pause/etc.) or to loop only once.
People should read their package manager's documentation for help using their package manager.
If you try to install just `units`, brew is smart enough to suggest it, however.
Of course, application developers may decide anyway to keep track of package names for their N favourite distributions and display them on their website. But to me it comes across as a waste of useful space.
echo -e '500 miles\nkm' | gnu-units-executable-name
But I'm pretty sure from reading the post that units prompts you first for 'you have' (units and/or measurement to convert) and then prompts you for 'you want' (units to convert to).This isn’t some new tool that is uncommon in UNIX systems, it’s something that a lot of OSs ship with their base install and have done for several decades.
The reason why that matters is because documentation was very different back then. People relied on ‘man’ pages and physical binders with printed instructions. READMEs did exist but they were plain text (not even markdown) and that was generally just there to explain how to compile the source (the compilation would create man pages)
As discussed elsewhere in the thread (https://news.ycombinator.com/item?id=25659223), it looks like macOS uses an early version of GNU Units.
It takes away the extra (to me) reciprocal conversion factors. (Note: it's the number one, not a lowercase "L".)
Without:
$ units
Currency exchange rates from FloatRates (USD base) on 2019-05-31
3460 units, 109 prefixes, 109 nonlinear units
You have: inch
You want: cm
* 2.54
/ 0.39370079
You have:
With: $ units -1
Currency exchange rates from FloatRates (USD base) on 2019-05-31
3460 units, 109 prefixes, 109 nonlinear units
You have: inch
You want: cm
* 2.54
You have:
To me the reciprocals are just clutter. If I want a reciprocal, I will just type the two parts of my query in the opposite order. I'd even say they're confusing because you have to look at them understand why there are two numbers.(Also on the subject of flags, I'd like one that suppresses the first two lines of output but not the prompts like "You have:".)
$ cat /etc/systemd/system/units-currency-update.service
[Unit]
Description=Update units(1) currency rates
[Service]
Type=oneshot
Nice=19
ExecStart=/usr/bin/units_cur
$ cat /etc/systemd/system/units-currency-update.timer
[Unit]
Description=Update units(1) currency rates
[Timer]
OnCalendar=daily
AccuracySec=3h
RandomizedDelaySec=3h
Persistent=true
[Install]
WantedBy=timers.target
# systemctl daemon-reload
# systemctl enable units-currency-update.timer 0 0 * * * nice -n 19 /usr/bin/units_cur
for *BSD crontabs or both HN users (besides me) who prefer systemd-free distros of GNU(1) The flag isn't for bc, of course; it's for units. I'm always running the wrong one, so no surprise I mixed them up again.
(2) Should read "look at them to understand" near the end.
units 40000lb tonnes
* 18.143695
It even includes currencies. "sudo units_cur" will update the exchange rate data file, if you need that. units 50GBP USD
* 68.143948Oh good tip that. I noticed the package on Ubuntu 20.04 came with currency conversion from 2019. Not very useful without updating it.
Doesn't work for XDR. Of course, who needs XDR? I sure don't. But you can get the XDR exchange rate with this command:
curl -d '__EVENTTARGET=lbnTSV' POST -v https://www.imf.org/external/np/fin/data/rms_sdrv.aspx
Maybe someone should integrate that into units_cur.
how is
C = (5/9)(F-32)
not linear?This follows from the constraint that for a linear map f, f(a + b) = f(a) + f(b), which is not true for the farenheit-celsius example.
EDIT: See https://en.wikipedia.org/wiki/Linear_function#As_a_linear_ma...
Reference: https://mathworld.wolfram.com/AffineFunction.html
f(c*(a+b)) = c*f(a) + c*f(b)
Where c is a scalar. A and b are abstract objects. Examples include vectors, real numbers, and functions themselves.Somewhat counterintuitive, but that's how it's defined.
> In mathematics, the term linear function refers to two distinct but related notions (...) [proceeds to specify them using incomprehensible math words]
GNU Units documentation uses the second notion, common with linear algebra (and thus arguably more common in any computing) - the notion that calls y=ax a linear function, and y=ax+b an affine function.
"Units only does multiplicative scale changes. Thus it can convert Kelvin to Rankine, but not Centigrade to Fahrenheit."
> But Fahrenheit to Celsius is linear, you insist. Not so. A transformation T is linear if T(x+y)=T(x)+T(y) and this fails for T(x)=ax+b . This transformation is affine, but not linear.
https://www.gnu.org/software/units/manual/html_node/Overview...
Frink started from and extended the units defined by Units, I don't know if anything has gone in the other direction.
Later: for simpler calculations an interesting feature frink adds is the ability to do interval arithmetic. Terms can be specified as ranges that are then carried through the calculations to the result.
It's a complex domain, especially if you get down to having more complex units composed of other units and want to do conversions between metric and imperial. In our case we were dealing with material properties (chemical, physical, magnetic, etc.) and different countries and companies using different ways to record characteristics for materials.
For example, if the conversion between two units is defined by statute to be some weird ratio, Frink will use that, and not merely the best f64 approximation of that ratio.
As indicated by a sibling comment, Frink also handles interval maths, and in general it just has a remarkable amount of features, being a fully-fledged programming language.
It's a pity it isn't open-source, the author says he doesn't want the aggravation of having to deal with pull requests and so on, and just wants to work on his software project on his own. Which, ok, that's fair: but at least Lua and SQLite don't accept contributions from outside the team, so there's a model for releasing open-source software without having to collaborate with the general public.
No question that it would increase the size of his inbox though, so I get it.
If GNU Units cannot do something, I resort to using Maxima[1].
This experience is why I stopped using W|A few years ago. It's awesome, but it's also a pain.
Kinda wish there was an open source browser-based WolframAlpha alternative which did more of the computation locally so everything wasn't so slow.
Just tested now and it does work on Android FF - yay! But not on my desktop (neither Chrome nor Edge). Doesn't work for me on Firefox nor Brave either (neither Win10 nor Kubuntu). I have randomly assigned IP from major UK provider (which provider has also changed). Doesn't work through my work VPN either.
I've taken to using Geogebra (online) when I quickly need a function plotting.
Edit: answering my own question. There are multiple providers, some requiring API-key signup, but the answer is far from definitive: https://www.gnu.org/software/units/manual/html_node/Currency...
You have: 1 lbs
You want: kg
* 0.45359237
/ 2.2046226
You have: 2 lbs
You want: kg
* 0.90718474
/ 1.1023113
You have: 2.4 lbs
You want: kg
* 1.0886217
/ 0.91859276https://www.gnu.org/software/units/manual/html_node/Interact...
"The second number gives the conversion in the opposite direction."
Try with 'units --verbose' and you get nicer output:
$ units lb kg
lb = 0.45359237 kg
lb = (1 / 2.2046226) kg You have: kg/day
You want: lb/hr
* 0.091859276
/ 10.886217V6 Unix (circa 1975) had it: http://man.cat-v.org/unix-6th/6/units
Your macOS have the BSD version:
% units -v
units version 1.0 Copyright (c) 1993 by Adrian Mariano
This program may be freely distributed
usage: units [-f unitsfile] [-q] [-v] [from-unit to-unit]The one in FreeBSD is from NetBSD: https://svnweb.freebsd.org/base/head/usr.bin/units/units.c?v...
The NetBSD version is from Adrian Mariano: http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/units/units....
The one in Plan9 is in yacc: http://9p.io/sources/plan9/sys/src/cmd/units.y
This GitHub repo claims to be V6: https://github.com/memnoth/unix-v6/blob/master/source/s2/uni...
For example, I'm in Austin, querying a database hosted in Amazon's us-east-1 data center ("Northern Virginia"). Call it 1000 miles away, 2000 mile round trip.
You have: 2000 miles
You want: millilightseconds
2000 miles = 10.736388 millilightseconds
If I have a query that's taking < 1ms, no optimization of how that query is executed by the database can possibly improve the overall performance.You kids gotta learn your damn history!
I tried converting torque "100 ft lbf" to standard ISO notation (Nm). Let's see:
units "100 ft lbs" "Nm"
> Unknown unit 'Nm'
units "100 ft lbs" "nm"
> conformability error
units "100 ft lbs" "newton meter"
> * 135.58
How am I supposed to know that 'newton' must be written in full (though 'ft' and 'lbs' can be abbreviated)? Searching for 'newton' in the manpage yields 0 results.Rejoice!
(but for real this is top I’m replacing multiple other tools with Units)
You have: kilometers per hour
You want: attoparsecs per microfortnight
* 10.889018I found myself wanting to calculate Little Boy blast yields sufficiently often that I added a hiroshimabomb unit of energy.
Similarly, various areal units such as countries and states/provinces.
Australian rules football grounds, even at the highest level of the game, have no fixed dimensions. For senior football, the playing field is an oval, typically between 135–185 metres (148–202 yd) long goal-to-goal and 110–155 metres (120–170 yd) wide wing-to-wing. Grounds can vary from long and narrow to almost circular, and are not necessarily symmetrical, depending upon how and where the field was constructed. At least 5 metres (5.5 yd) of space between the boundary line and any fence is required for safety.
https://en.wikipedia.org/wiki/Australian_rules_football_play...
Canadian Football: 150 yards length overall, 65 yards width overall. 2.0144628 acres area, 0.81522418 hectares.
https://sportsknowhow.com/football/field-dimensions/canadian...
The other question is if you're looking for length or areal metrics.
I've written a few quick guides and examples using GNU units:
GNU 'units' utility and energy / resource calculations
https://old.reddit.com/r/dredmorbius/comments/1x9u0f/gnu_uni...
How many Hiroshima bombs in a Ferrari, with mass-energy conversion (or how I learned to extend GNU units)
https://old.reddit.com/r/dredmorbius/comments/1yvxde/how_man...
And for assessing specifc alternative energy claims:
Boeing's Biofuel "Breakthrough" -- Less than overwhelming
https://old.reddit.com/r/dredmorbius/comments/1wo2hl/boeings...
How does it compare?
$ qalc
> furlongs per fortnight
furlong / fortnight = 1 fur / fortnight
> to m/s
1 fur / fortnight = approx. 0,0001663095238 m / s
> 17 yards + 2 feet + 5 inches
(17 * yard) + (2 * foot) + (5 * inch) = 17 yd + 2 ft + 5 in
> to meter
17 yd + 2 ft + 5 in = 16,2814 m
> $ units --verbose
[header]
You have: furlongs per fortnight
You want: m/s
furlongs per fortnight = 0.00016630952 m/s
furlongs per fortnight = (1 / 6012.8848) m/s
You have: 17 yards + 2 feet + 5 inches
You want: meter
17 yards + 2 feet + 5 inches = 16.2814 meter
17 yards + 2 feet + 5 inches = (1 / 0.06141978) meter
Personally, I find qalc via qalculate-gtk more useful for exploratory sessions but I still use units an awful lot.For example, 1500 mAh (milliamp∗hours) could be converted to 5.55 Wh (watt∗hours), or 19.98 kJ in SI units, in the context of a 3.7-volt battery.
Naive approach fails:
$ units "1500 milliampere*hours at 3.7 volts" "watt*hours"
conformability error
1.9593687e+09 kg^2 m / s^4
3600 kg m^2 / s^2 You have: 1500 mA * hr * 3.7 V
You want: kJ
* 19.98
/ 0.05005005
You have: 1500 mA * hr * 3.7 V
You want: watt * hours
* 5.55
/ 0.18018018 You have: 1500 mA hours * 3.7V
You want: W hours
* 5.55
/ 0.18018018 You have: 1500 mA * hours * 3.7 V
You want: watt * hours
* 5.55
/ 0.18018018I'd like to have a look at the code but all I found is an outdated mirror : https://github.com/ryantenney/gnu-units
http://savannah.gnu.org/projects/units
All official GNU software is hosted here: http://savannah.gnu.org
Unfortunately it looks like the upstream for this project is in... cvs
(Slightly discombobulating to read some of today's lucky 10,000 treating `units` as a (GNU) novelty when it's been around for 40+ years.)
It's almost as if humans spent thousands of years inventing units without ever once considering how difficult they might be to implement in a computer programming language.
Most of the world doesn't care about the thousand-year units, and the bit that does could just convert to them on output.
And that’s before you get into the technical details of how you store units and conversion factors in memory, how you handle precision when mixing large and small units, how you interact with unlimited‐precision and rational numbers, how you use or avoid the type system in your programming language, how users of your unit library define their own units…
Here’s a good write‐up of what they’re thinking about for future versions of C++: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p193.... It’s worth a read even if you don’t write in C++.
And if you bake it into your language, you’d better get it all right the first time, because you probably won’t be able to fix it later.
if the units don't match then the operation was an error: 1_ft + 1_gal => error
As other people have mentioned I really wish spreadsheets had this built-in where units are like formats for a cell. Ii controls about how you want things displayed and will prevent you from making conversion mistakes or doing illegal operations.
https://www.gnu.org/software/emacs/manual/html_node/calc/Uni...
Is there a way to get inches in ruler-based fractions instead of decimals? Imperial rulers don't give you tenths or hundredths of an inch, so I would find it much more useful if the output were "just under 22ft + 11 19/32in" or something similar.
Google did it well for the longest time, then stopped at some point. Now it works again.
Just tried it on iOS and it works now. Don’t quite remember when I last tried, but I believe it’s fairly recent.
$ units "6 l/100 km" mpg
reciprocal conversion
* 39.202431
/ 0.025508622 units "30 miles per gallon" "liters per 100km"
reciprocal conversion
* 7.8404861
/ 0.12754311 LANG=en_GB.UTF-8 units "30 miles per gallon" "liters per 100km"
reciprocal conversion
* 9.4160312
/ 0.10620186
LANG=en_US.UTF-8 units "30 miles per gallon" "liters per 100km"
reciprocal conversion
* 7.8404861
/ 0.12754311
(Although it is incomplete, as it only uses Imperial gallons for "gallon" for en_GB, although there are probably more English locales that use(d) the Imperial gallon than the US gallon.) 203: Ideas the future (may or may not happen):
204:
205: * Bundle up the units conversion stuff into a library.
At the end of units.c, too: 6280: /* NOTES:
6281:
6282: mymalloc, growbuffer and tryallunits are the only places with print
6283: statements that should (?) be removed to make a library. How can
6284: error reporting in these functions (memory allocation errors) be
6285: handled cleanly for a library implementation?
6286:
6287: Way to report the reduced form of the two operands of a sum when
6288: they are not conformable.
6289:
6290: Way to report the required domain when getting an domain error.
6291:
6292: */
My prowling of the source code is probably uninformed because I'm not a C expert by any means but it seems like you could include units.h and use many of the useful functions in another program.It implements units using a ton of templates and "compile-time metaprogramming". [0]
The nice thing is that it has no runtime overhead as all templates are "compiled away". The disadvantage is that when you make a mistake against units, it results in a "template compiler error explosion".
[0]https://www.boost.org/doc/libs/1_65_0/doc/html/boost_units.h...
Example query to estimate how much electricity bitcoin miners can afford to use at current prices:
https://www.wolframalpha.com/input/?i=%28%286.25+bitcoin+%2F...
I don't know how it derives/compares to the gnu version
$ units -v
units version 1.0 Copyright (c) 1993 by Adrian Mariano
This program may be freely distributed
It doesn't do temperature (which would make it more useful)ERR: A1 is USD/month, B1 is USD/user, so you cannot calculate A1+B1!
Gotta love that a bushel of Yellow Corn is a different weight than a bushel of Oats.
huh?
Obviously there are some stark philosophical differences between GNU and the walled gardens of mobile devices. But users don't care about that, they just want good software.
% units --verbose -1 '4080mA hours * 5V' btu
4080mA hours * 5V = 69.607689 btu You have: 1 kelvin
You want: degcelsius
* 1
/ 1
This does not seem rightCompare:
You have: 1 degF
You want: degcelsius
* 0.55555556
/ 1.8Notice you also don't need degrees metre, degrees watt or degrees newton, because those are absolute units they are metres, watts and newtons. It is Celsius (and Fahrenheit) which are weird because they aren't absolute but instead have this arbitrary zero point.
You have: tempK(1)
You want: tempC
-272.15> Conversions between temperatures are different from linear conversions between temperature increments—see the example below. The absolute temperature conversions are handled by units starting with ‘temp’, and you must use functional notation. The temperature-increment conversions are done using units starting with ‘deg’ and they do not require functional notation.
From the man page: Nonlinear units are represented using functional notation. They make possible nonlinear unit conversions such as temperature.
You have: tempK(1)
You want: tempC
-272.15
Edit: seems i am not alone :D./units "3 km in miles" Definition: 122632.01 m^3
My physics lessons at secondary school must have spent at least a week on SI units, base and derived units:
Force = mass × acceleration
N = kg × m·s¯²
(i.e. a Newton is a kilogram-metre-per-second-squared.)
Pressure = force ÷ area
Pa = N ÷ m²
Pa = kg·m·s¯² ÷ m²
Pa = m¯¹·kg·s¯²
(So Pascals are Newtons-per-square-metre, or kilograms-per-metre-per-second-squared.)Is that a pipe for division?
We need to see this ^ more often in real life!
(yes i'm joking, but considering all the other freedom units, and rules measuring in 1/64", it's not far from the truth)
The heck? "y = ax + b" is linear; just not homogeneous linear.
https://en.wikipedia.org/wiki/Fahrenheit#Definition_and_conv...
It is a linear equation, confusingly enough.
A scaling plus displacement is linear in the sense of "linear equation" because, for instance, if you scale a signal and add DC offset, there is no distortion; no new harmonics are present in the output signal.
ax + by + c is called linear because the plot of points which satisfy the equation form a straight line; there is nothing confusing about it whatsoever.
Temperature delta conversions between C and F are certainly a linear map/operator. If it gets 5°C hotter, and then 3°C hotter, making 8°C hotter, that's exactly like 9°F hotter plus 5.4°F hotter making 14.4°F hotter.
Here is a test for linearity for a real-valued one-argument function which is not confused by an offset:
x + y f(x) + f(y)
f( ------ ) = -----------
2 2
Works just fine for °C/°F.There is another criterion for a linear map that hasn't been mentioned, though: f(ax) = af(x).
That said I completely agree that it makes way more sense to just call it a linear conversion and to pick an example that's truly nonlinear. Not that there are that many non-linear units, but something like decibel or beaufort might work.
https://en.wikipedia.org/wiki/Linear_function
A "linear function" refers to a "linear map" only in certain contexts.
The word "affine" can be used for a mapping that fails to meet the definition of a linear map operator due to offsets. That is much better than "nonlinear".
Zero degrees Fahrenheit is of course not equal to 0 K, but conversion of absolute temperature is not presented as the best example of this class of unit conversion. It's highlighted because everybody asks about it. Temperature conversion was for years, before I figured out a way to support it elegantly, the most requested missing feature. Yes, it's a little strange to call affine transformations "nonlinear" but there is no special "affine unit" feature in the program.