As I understood it: C to K would be linear since they are always offset by the same amount, but 0°C is not 0°K. C to F is not linear since they are not offset by the same amount.
It seems to me C to K is affine as well. True, it's somewhat special in that the factor is exactly one, but if there's an offset it's not linear in the sense of the sentence under discussion.
That's not how it works. The definition of linear used in this context requires f(a+b) = f(a) + f(b) which is not the case with the C to K translation which is f(x) = x + 273.15 Only functions in the form y=mx+0 meet the criteria.
> 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.
So, rather than calling it non-linear, which is clearly somewhat confusing, perhaps it would be more clear to state that it handles affine functions like F to C...?
Agreed. Why they wasting our time pointing out it’s “non-linear” when this statement is only true for some definitions of linear? Just pick a non-ambiguous word, or add an asterisk and footnote.
> 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.
Units is older, frink is a lot bigger, it's a whole programming environment.
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.
The author of Frink takes particular pride in doing unit maths correctly.
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.
I love being able to convert from millilightseconds to miles, and vice versa. You can figure minimum latency for a given distance or maximum distance for a given latency.
Probably not. Knowing the speed-of-light round trip time to a network location gives you a bound on how much you can improve the performance of remote operations.
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 could count it in increments of some number, like 1280... so you'd have a car speedometer which would measure your speed in x*1280 furlongs/forthnight.
(yes i'm joking, but considering all the other freedom units, and rules measuring in 1/64", it's not far from the truth)
Not the unit definitions in a spreadsheet; I'd like a spreadsheet where each cell has not just a number, but a number with its unit. Formulas would be evaluated the way `units` does it. B1=3m; B2=4s; B3="=B1/B2" would give as value of B3 "0.75 m/s".
$ 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:
In the README in the GNU units source code (2.21):
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".
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.
I've been using WolframAlpha for this sort of thing. The idea of using something fully local and open-source does have some appeal, but it's hard to compete with the convenience of Ctrl+T "wo" <Tab> <Query> <Enter>.
You mean Ctrl+T "wo" <Tab> <Query> <Enter> <Wait 15 to 60 seconds for the page with your results to load> <Get something that's a mighty pain to copy/paste from>.
This experience is why I stopped using W|A few years ago. It's awesome, but it's also a pain.
Can relate; that's definitely been an issue for me as well. Though on the plus side it's nice to be able to open multiple tabs, make small tweaks to the formula, and switch between them to compare results.
Kinda wish there was an open source browser-based WolframAlpha alternative which did more of the computation locally so everything wasn't so slow.
I used to love Wolfram Alpha but it hasn't worked for me for several years and I've been unable to find out why.
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.
If Units can convert between currencies, how does it source the exchange rates? They change on sub-second time scales and bid/ask spreads make the notion of a rate somewhat uncertain.
Looks cool. If the poster is affiliated with the project, some suggestions:
1. 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.
No please don't use a gif. That's a terrible way to present information and leads to accessibility issues in documentation where it has no business. Instead, just show a shell prompt and the command needed to launch the program.
So long as those with disabilities are also accounted for, using gifs are a great way to demonstrate usage. I always appreciate running across them when I hit a readme.
I dislike them, but I see one benefit: they increase effective screen real estate by leveraging time as an additional dimension.
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.
I see how they're useful, but I'm still not fond of them because:
(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.
I agree with you, but package names aren't predictable. I find that an example of installing a package is helpful even for users familiar with use of package managers as it gives context and helps readability. Whenever I see `sudo apt-get somethingsomething` I immediately know that somethingsomething is the package name.
Application developers typically do not decide package names (unless they provide their own package repository), distribution maintainers do. Package names may change over time, and might be different for different distributions (or even between different versions of the same distribution), even if they use the same package format.
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.
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 is a GNU implementation of an old UNIX tool. It’s older than Linux, let alone package managers. There’s also BSD and other implementations available (the BSD version comes pre-installed on macOS).
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)
It's very important to watch out for useless uses of echo/cat. What is cat, a few megabytes now? Fine for those of us on modern hardware, but you never know what PDP-11 user is going to copy paste your comment into their terminal.
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.
> 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?
It's relevant information if you're converting to mass, which was probably the intention. Google will return the correct result for "mass 1 cup flour", by comparison.
There is no correct way to turn "1 cup flour" into a mass. For one thing, you can fit more into the same volume by compressing. But more importantly, the material is ambiguous. There are many different kinds of flour with varying physical properties.
I started using this tool some years ago after I found out the CO₂ cost of a Google search. I don't need a web query when I search "40000lb in tonnes" when reading an American news article, for example.
units 40000lb tonnes
* 18.143695
It even includes currencies. "sudo units_cur" will update the exchange rate data file, if you need that.
I absolutely adore this program. It works exactly like I expect, every time. Sometimes I'll just think about what a nice tool it is, even when I'm not using it.
What I particularly like is the use of the locale:
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.)
I keep using different tools to do conversions so now I can unify that all into Units and get my speed in furlongs per fortnight as the ancient prophecies foretold.
Rejoice!
(but for real this is top I’m replacing multiple other tools with Units)
It's right in the sense that the units are the same size. IE if something increases 10 deg K it also increases 10 deg C. But it's obvious to humans that that isn't what you where asking.
Compare:
You have: 1 degF
You want: degcelsius
* 0.55555556
/ 1.8
Nitpick: There are no "deg K", because it is an absolute system it doesn't have degrees.
Notice 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.
> 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.
It has both / for division with the usual precedence and | for very tight-binding division, for use in fractions. So 1/6 cup parses as 1/(6 cup) but 1|6 cup parses as (1/6) cup.
That's linear in the sense of "linear operator" or "linear map". I've never heard "nonlinear" as the opposite of that due to to a constant offset. "Linear map" and "linear operator" are used in contexts where homogeneity is a given.
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).
Well one way or another it's not a linear function, so calling it a non-linear conversion is technically not incorrect.
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.
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".
GNU units supports normal unit conversion, such as meters to feet. These conversions all obey f(ax)=af(x), that is, if you have zero meters you have zero feet. If you want to convert something that breaks that rule then you have to give a definition in the database as a general functional form or as a lookup table. And you have to use functional syntax to perform the conversion. Some examples in the database include dB, wire gauge, shoe size, grit size for sandpaper, ring size, musical intervals, and sugar concentration. I call units defined using a lookup table or general functional form "nonlinear units".
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.
% 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]
It’s about Unix, and GNU’s Not happens to be the best implementation of it. Which is why macOS copies pieces of it, despite needing to use obsolete versions in order to comply with Apple’s hatred for end-user freedom.
I’ve always wondered why units(1) isn’t a library. I’d love to have access to abstract “united quantities” and “united measurements” in my HLL of choice, rather than needing to switch to a special-purpose tool (units, Frink) or a statistical-analysis language like R just to get them.
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.)
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.
There are heaps of libraries for all languages because it is a fairly fun and straight forward project. I personally created this one because I was frustrated with how slow and clunky the existing javascript libraries were:
What makes you say that? I suppose you could add as much complexity as you want with differentiating units from different standards and adding uncertainty in the unit definitions and on and on. But for 99% percent of users, just conversion factors and basic arithmetic operations are all that is needed. What application do you have in mind where this would fall short? In 15 years as an engineer I have not run into one.
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.
Commenting on my own thread because the window to edit has passed. What is up with the haters today? I share a useful open-source library with everyone that I spent a ton of time working on only to get crapped on by the know-it-all crew? Did you even click the link and read the github readme? This library is tested against NIST data! It also has 100% test coverage and support for corner cases like non-linear unit conversions like temperature. How does anyone enjoy participating in this community?
HN has a huge number of users, most of whom don't comment on any given topic. So I think it's best to not care too much what the handful of individuals who interact with you happen to think.
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
The source isn't that big, I just downloaded 2.21 source and it is one directory with about ~45 files, and the majority of bytes are for /doc/dvi binaries, only 5 c files and a post Yacc'd tab file for parsing the units definitions file. Surprisingly simple now that I look at it.
Heck... I was going ask you to write it, but now I'm thinking this could be a fun weekend project.
Keeping track of units was one of the first ever uses of C++ templates (one of the Bjarne books IIRC mentions it existing prior to the STL), but was apparently reinvented multiple times later.
FYI: use tab completion in the 'units' REPL to show a list of available definitions. You won't find them in the 'units' manpage, as they are defined in an external datafile (on my machine this file is /usr/share/units/definitions.units)
214 comments
[ 3.0 ms ] story [ 235 ms ] threadhow is
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
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.
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.
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.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)
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.
How much power could you obtain with a small water turbine if you had 10m of head and 1l/s ? Easy !
0: https://github.com/sharkdp/insect
586 units, 56 prefixes
You have: 50m * 1kg/s * gravity
unknown unit 'gravity'
how did you get gravity?
EDIT: Figured it out, just had to brew install gnu-units
https://frinklang.org/
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...
https://en.wikipedia.org/wiki/FFF_system
I 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.
If GNU Units cannot do something, I resort to using Maxima[1].
[1] https://maxima.sourceforge.io
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...
I'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.)
1. 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.
[0] https://www.gnu.org/software/units/manual/units.html
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.
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.
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...
[1]: https://www.ibiblio.org/harris/500milemail-faq.html
> 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?
[1] https://www.ibiblio.org/harris/500milemail-faq.html
I love that every time this link gets posted to HN someone says it looks like a hoax.
Oh 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.
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.
1: https://pint.readthedocs.io/en/stable/
Rejoice!
(but for real this is top I’m replacing multiple other tools with Units)
Compare:
Notice 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.
> 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.
Edit: seems i am not alone :DFor 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:
Is that a pipe for division?
The heck? "y = ax + b" is linear; just not homogeneous linear.
https://en.wikipedia.org/wiki/Fahrenheit#Definition_and_conv...
https://en.wikipedia.org/wiki/Homogeneous_function
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:
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.
V6 Unix (circa 1975) had it: http://man.cat-v.org/unix-6th/6/units
Your macOS have the BSD version:
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...
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:
https://github.com/GhostWrench/unitdb
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:
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: