What? How did the last digit end up as '4'? That's no kind of rounding I've ever heard of!
So I ran `bc` on my machine and tried:
[jeff@prism:~/path]$ bc -l
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
scale=8;
4*a(1)
3.14159264
scale=16;
4*a(1)
3.1415926535897932
I guess you could say "learn bc before using it", but even after a quick skim of the man page, this is not what I would expect.
So I don't know what a(1) is supposed to represent (and am purposefully not looking it up before thinking about this due to your comment about the man page) but presumably it is pi/4 (as 4 times that is pi). If you take pi/4 and round it to 8 decimal digits of precision you get 0.78539816. If you multiply that by 4 (and round it to 8 decimal digits of precision, though this result already has that precision) you get 3.14159264. I guess you are assuming intermediate results somehow have tons of excess precision? (edit: After writing this I checked the man page and a is apparently arctangent.)
I hadn't thought about when bc does its truncation with the scale variable, but your explanation appears to be exactly right. With scale=8, a(1) returns .78539816, which is already truncated to 8 digits.
There is some discussion on intermediate result truncation (not exactly in those terms) in the "EXPRESSIONS" section of the bc(1) man page. It notes that "Every expression has a scale", and elsewhere the man page notes that "All numbers are represented internally in decimal and all computation is done in decimal".
> What? How did the last digit end up as '4'? That's no kind of rounding I've ever heard of!
Have you memorized pi to nine significant places, or how did you even notice?
BC implements arbitrary precision arithmetic with decimals (try
echo 'scale=10000; 4*a(1)' | bc -l
and make yourself a cup of coffee), so it's not that surprising that it will give you an incorrect final digit. To guarantee correct rounding of the last displayed digit you need to be able compute to arbitrary precision in the general case, I don't think bc does that and that scale does not just govern number of (trailing) digits displayed but also also precision of computation.
> Have you memorized pi to nine significant places, or how did you even notice?
Not the OP - but, yes. My memory runs to 3.1415926535 and gets a little fuzzy after that, I think it's 2949 or something without looking... hrm, nope; 8979. Good thing I wasn't sure.
Definitely as much as any reasonable human scale thing and then some, but memorising a calculator screen full of Pi isn't that impressive. It used to be written above the stairwell in the maths dept at Uni, so I walked past it multiple times per week for years.
Can you explain how this "go-to approximation" is ever useful to you?
I don't understand why anyone would memorize pi to more than 3 digits, other than by accident (such as the sibling, who just saw it on a campus wall countless times).
Those 3 digits are good for ~0.05% error, plenty good enough for any mental calculation you might want to do. In any other context you would have pi trivially available as a constant anyway, right?
Maybe "go-to" is the wrong word. It's just that those are the digits I remember off the top of my head. I don't remember whether I made an actual effort to memorize them as a kid, it's been over twenty years. But they stuck and are not easy to forget now.
People whinge about IPv6 not being worth it but two of the things included in its ergonomics are hexadecimal address notation and netmasks that are multiples of 4.
And IPv6 addresses are long and unmemorable? Addresses that you actually need to memorise are, in practice, only as long as your routing hierarchy is deep.
Your site:
2001:db8:60::/48
Your office LAN:
$site:12
Your printer:
$site:12::4
*
>>> f = lambda q: '0x{:08x}'.format(reduce(int.__or__, (n << i * 8 for n, i in zip(map(int, q.split('.')), reversed(range(4))))))
The IPv4 spec does not mention octal (or hexadecimal) notation at all; allowed forms are purely determined by individual APIS or user interfaces. POSIX `inet_addr` (and non-POSIX `inet_aton`) support nondecimal notation; the more recent POSIX `inet_pton` does not (but supports both IPv4 and IPv6 addresses). Support of oct and hex notation in the older APIs is mostly a historical accident. RFC 6943 recommends only supporting what they call "strict format" in newly written code [1].
Yeah, IPv6 being variable length hexadecimal makes it difficult for people to pattern match. I can typically expect that users know what the four groups represents, but IPv6 being represented in such varying ways means that I can't expect the same of it.
Imagine a file system where 2 or more users could have independent permissions to a file without being members of a single shared group or sharing with the world or using bolt-on software to enforce.
My non-base-ten mental arithmatic isn't great, it's rare I need to do it (my typical subnets are /27 or /28, very rare I'll have a /23 or larger) so I hit alt-enter to open up a new terminal, type "bc", and job done
~$ bc
obase=256
253+10
001 007
But adding 10 to 0xfd? That involves converting 10 to 0xa, then adding to FD
But at least it's more useful. Much easier to subnet, even outside of nibble boundaries, because just looking at the number you'll immediately see what bits are set.
It's the colons that do it, in my opinion. They visually fill the gaps between segments, which makes it harder to pick out what is a digit and what is "empty space". Compare:
6d08:048c:4c3b:57f0:0bca:f236:e8ab:b52e
with
6d08-048c-4c3b-57f0-0bca-f236-e8ab-b52e
Though the best solution is to fully embrace the ASCII lifestyle that modern teletypes allow, and use the record separator 0x1f:
(I'll take this opportunity to repeat an earlier bikeshed of mine, which is that IPv6 address syntax should have used hyphens instead of colons, and dealt with the ensuing "is it a hostname or ip address?" problem by always requiring square brackets:
The thing that holds me back with IPv6 is not the notation, but that you have to take account the outside world into consideration when you assign local IPs. It's a bit like needing globally resolvable DNS names in your local net.
With IPv4, you just stick to an IP range that has not been assigned, and just hand out addresses. You don't even have to understand subnets properly. The net mask just tells you when a packet goes to another computer directly vs. via a gateway. It's all very direct and basic.
Compared to IPv6 where it feels like there are five different kinds of addresses, and a part of the address comes from some external authority, a part is random, and a part is assigned by you. We have had telecom technicans and IT contractors come in to set up our network and the first thing they both did was to disable IPv6, with a comment like "hell god no you don't need that stuff". They didn't seem to understand it either.
> but that you have to take account the outside world into consideration when you assign local IPs
It was supposed to be this way with IPv4 as well, until we ran out of addresses. Imagine if we did not have IPv4 address exhaustion and Comcast would give you a full /24. So you have xxx.xxx.xxx.0 to xxx.xxx.xxx.255 for your home network.
> part of the address comes from some external authority
Part of any public IPv4 comes from some external authority, that's what the subnet mask delineates. People are too stuck on NAT and as a result we'll never have a truly decentralized Internet. I will say I'm having trouble wrapping my head around the need for "link-local" stuff - isn't that Layer 2's job?
I guess many people (me included I confess) use NAT as a poor man's firewall. So having a separate link-local "address space" is a feature, not a bug.
Also, considering how often I have to deal things like somebody setting a wrong static IP on a device, it comforts me that this is not unleashed on the greater internet, but all I can mess up is my own LAN...
1. Without delimitation, everything becomes long and confusing (including a single hexadecimal number for IPv4).
2. You absolutely lost me with your IPv6 example:
* I need to remember whether to use one colon or two, for each delimited number
* How do I even know the range of each delimited value is the same?
* How can I be sure what basis each of the delimited values is? I mean, you can tell me it's hex, but without someone telling me, I'm never quite sure.
With IPv4, it's easy: Four dot-delimited numbers, each between 0 and 255, in decimal notation.
Convenience and notation variance are more confusing than useful. If it had just been 8 numbers, with no ommissions or replacements, I would have better been able to keep track.
The first 64 bits are the network and the last 64 bits are the host address. You write them out in groups of four hex chars (16 bits per group) separated by colons.
To make them a little more memorable, leading 0s in a group can be omitted, and '::' will be expanded to fill the middle of an address with 0s.
The 64/64 split is always the same for local networks, unlike IPv4 CIDR where the widths of each part are based on how rich you are :)
In full, without any abbreviations, `2001:db8:60:12::1` breaks down into:
`2001:db8::` – your ISP.
`2001:db8:60::` – you, their customer. This is the number you end up typing a lot, just like you type "31.101.24.xxx" if you are lucky enough to own an IPv4 /24.
`2001:db8:60:12::` – an actual network, in this case your network number 12, e.g. your toilet soap dispenser level monitoring network
`2001:db8:60:12::1` – soap dispenser controller PC
`2001:db8:60:12:7223:24ff:fe02:844e` – random soap dispenser with a giant weird self-assigned address that you don't need to care about remembering because the dispenser connects to your controller PC, not the other way around (if you did, you'd assign it a memorable address :P)
A basic problem with the IPv6 dotted quad is the fact that it is a quad. Humans can easily discern at a glance at most 3 symbols, which is a major point in favor of the IPv4 decimal notation. It's easier to visually distinguish 101 from 110 than it is to distinguish 1011 from 1101, especially in the context of multiple such groups.
Also, your "your site" example is deceptively simple. It works nicely if your /48 happens to be full of 0s, but even assuming you were allocated a huge /32 and you got to choose the extra 16 bytes for memorability, the address is more likely to be something like 2a00:1450:4001:830::/48.
Even this seems overly optimistic. For example, www.google.com is not a /48, but seems to be closer to /124 from some basic probing: 2a00:1450:4001:830::2000 to 2a00:1450:4001:830::200f seem to all respond as www.google.com, but 2a00:1450:4001:830::2010 does not.
If Google chose not to allocate a whole /48 to www.google.com, I doubt many sites would.
So we're on the page, when I say "site" in this case it means a location to which lots of traffic for many different hosts is routed. (Not "site" as in "website".)
Typically a University campus, or a company office block, or a datacentre, or your whole distributed org if you hang the networks for your other global offices off VPNs behind one front-end site.
>Humans can easily discern at a glance at most 3 symbols
Are you sure about this, or have a source where I can read more? There are some counterpoints: both Japanese and Chinese use four-digit grouping for numbers, and it's common to see things like credit cards use four-digit groups.
Not OP and not my field of study but this seems relevant.
>Variations in the amplitude of the N400 showed a better memory trace for items presented in [temporal groups] of three compared to those in groups of four.
Having been allocated a /32 I think there is some confusion here. You still assign /48s to sites. Sites being physical locations your routers are at, not websites. Inside a site you assign /64 networks per VLAN, such as site:12::/64. Devices in that VLAN can dynamically get an address or be assigned one such as the printer so site::12::4/64 is your printer 4 on the 12th subnet at your 16 bit site prefix of your 32 bit global scope. Smaller orgs may have less than 16 bits for their site prefixes, all the way down to just having a single /48 assigned to them.
This is similar to how many smaller orgs used 10.site.vlan.device but obviously it scales larger (site and vlan can each be 16 bits instead of 8) and everybody gets a unique public replacement for "10."
If you like this, then you might like earlier discussions about this too. [0][1]
I remember seeing a very colorful page (literally) about this around 1997 and it totally blew my mind back then. Sadly I have no idea on how-to locate that page again.
Personally, I make use of this all the time. My home network uses the 10.0/8 subnet, so I'll naturally use 10.137 in commands like ping, ssh, curl, ifconfig. Other than web browsers and the `ip` command, virtually everything that I might enter an IP address in seems to support the two- and three-part addresses. I've always thought of the lack in `ip` as a bug [0]; `ip route add default via 10.138` seems to misinterpret the address as 10.138.0.0 (or as I would say, 10.138.0).
Note that this is also nice for loopback addresses. Normally the loopback interface owns all addresses in the 127.0/8 subnet, so you can listen on any address from 127.1 to 127.16777214.
> may be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal; otherwise, the number is interpreted as decimal)
58 comments
[ 4.3 ms ] story [ 132 ms ] threadSo I ran `bc` on my machine and tried:
I guess you could say "learn bc before using it", but even after a quick skim of the man page, this is not what I would expect.I hadn't thought about when bc does its truncation with the scale variable, but your explanation appears to be exactly right. With scale=8, a(1) returns .78539816, which is already truncated to 8 digits.
There is some discussion on intermediate result truncation (not exactly in those terms) in the "EXPRESSIONS" section of the bc(1) man page. It notes that "Every expression has a scale", and elsewhere the man page notes that "All numbers are represented internally in decimal and all computation is done in decimal".
Have you memorized pi to nine significant places, or how did you even notice?
BC implements arbitrary precision arithmetic with decimals (try
and make yourself a cup of coffee), so it's not that surprising that it will give you an incorrect final digit. To guarantee correct rounding of the last displayed digit you need to be able compute to arbitrary precision in the general case, I don't think bc does that and that scale does not just govern number of (trailing) digits displayed but also also precision of computation.Not the OP - but, yes. My memory runs to 3.1415926535 and gets a little fuzzy after that, I think it's 2949 or something without looking... hrm, nope; 8979. Good thing I wasn't sure.
Definitely as much as any reasonable human scale thing and then some, but memorising a calculator screen full of Pi isn't that impressive. It used to be written above the stairwell in the maths dept at Uni, so I walked past it multiple times per week for years.
At least my "go-to" approximation is 3.141592654 due to the nice descending 654 at the end.
I don't understand why anyone would memorize pi to more than 3 digits, other than by accident (such as the sibling, who just saw it on a campus wall countless times).
Those 3 digits are good for ~0.05% error, plenty good enough for any mental calculation you might want to do. In any other context you would have pi trivially available as a constant anyway, right?
Count the number of 0s at the ends of each of these:
People whinge about IPv6 not being worth it but two of the things included in its ergonomics are hexadecimal address notation and netmasks that are multiples of 4.And IPv6 addresses are long and unmemorable? Addresses that you actually need to memorise are, in practice, only as long as your routing hierarchy is deep.
Your site:
Your office LAN: Your printer: *http://3509828724/
If you feel sadistic, it's also legal to use octal encoding.
http://0321.0063.0274.0164/
[1] https://datatracker.ietf.org/doc/html/rfc6943#section-3.1.1
Decimal representation didn't make much sense either but we have decades of normalizing it.
Why is 255 the max in an octet?
Why do we call them octets?
I have a /23 and I want to add 10 to 192.168.0.253, how can I do this?
0.253 + 10 = 1.7
0xfd + 0xa = 0x107
Which one makes more sense?
We like the decimal representation because that's how we grew up. It doesn't actually make much sense.
setfacl exists is supported for years (although I prefer windows file permission logic to be honest)
It's an 8 bit value
> Why is 255 the max in an octet?
255 is the largest 8 bit value
~$ bc obase=256 253+10 001 007
But adding 10 to 0xfd? That involves converting 10 to 0xa, then adding to FD
~$ bc obase=16 10 A ibase=16 FD+A 107
Far more involved.
With IPv4, you just stick to an IP range that has not been assigned, and just hand out addresses. You don't even have to understand subnets properly. The net mask just tells you when a packet goes to another computer directly vs. via a gateway. It's all very direct and basic.
Compared to IPv6 where it feels like there are five different kinds of addresses, and a part of the address comes from some external authority, a part is random, and a part is assigned by you. We have had telecom technicans and IT contractors come in to set up our network and the first thing they both did was to disable IPv6, with a comment like "hell god no you don't need that stuff". They didn't seem to understand it either.
It was supposed to be this way with IPv4 as well, until we ran out of addresses. Imagine if we did not have IPv4 address exhaustion and Comcast would give you a full /24. So you have xxx.xxx.xxx.0 to xxx.xxx.xxx.255 for your home network.
> part of the address comes from some external authority
Part of any public IPv4 comes from some external authority, that's what the subnet mask delineates. People are too stuck on NAT and as a result we'll never have a truly decentralized Internet. I will say I'm having trouble wrapping my head around the need for "link-local" stuff - isn't that Layer 2's job?
Also, considering how often I have to deal things like somebody setting a wrong static IP on a device, it comforts me that this is not unleashed on the greater internet, but all I can mess up is my own LAN...
2. You absolutely lost me with your IPv6 example:
With IPv4, it's easy: Four dot-delimited numbers, each between 0 and 255, in decimal notation.Can you describe valid IPv6 addresses like that?
For convenience, one stretch of all-0 numbers can be omitted. FFFF::2:1
For bizarre reasons, the last 2 numbers can be replaced with an IPv4 address... FFFF::0.2.0.1
The first 64 bits are the network and the last 64 bits are the host address. You write them out in groups of four hex chars (16 bits per group) separated by colons.
To make them a little more memorable, leading 0s in a group can be omitted, and '::' will be expanded to fill the middle of an address with 0s.
The 64/64 split is always the same for local networks, unlike IPv4 CIDR where the widths of each part are based on how rich you are :)
In full, without any abbreviations, `2001:db8:60:12::1` breaks down into:
`2001:db8::` – your ISP.
`2001:db8:60::` – you, their customer. This is the number you end up typing a lot, just like you type "31.101.24.xxx" if you are lucky enough to own an IPv4 /24.
`2001:db8:60:12::` – an actual network, in this case your network number 12, e.g. your toilet soap dispenser level monitoring network
`2001:db8:60:12::1` – soap dispenser controller PC
`2001:db8:60:12:7223:24ff:fe02:844e` – random soap dispenser with a giant weird self-assigned address that you don't need to care about remembering because the dispenser connects to your controller PC, not the other way around (if you did, you'd assign it a memorable address :P)
I cannot get my ISP to allocate me a SINGLE static ipv6. So it's much MUCH more expensive to get an ipv6 address than an ipv4 static IP address.
Also, your "your site" example is deceptively simple. It works nicely if your /48 happens to be full of 0s, but even assuming you were allocated a huge /32 and you got to choose the extra 16 bytes for memorability, the address is more likely to be something like 2a00:1450:4001:830::/48.
Even this seems overly optimistic. For example, www.google.com is not a /48, but seems to be closer to /124 from some basic probing: 2a00:1450:4001:830::2000 to 2a00:1450:4001:830::200f seem to all respond as www.google.com, but 2a00:1450:4001:830::2010 does not.
If Google chose not to allocate a whole /48 to www.google.com, I doubt many sites would.
Typically a University campus, or a company office block, or a datacentre, or your whole distributed org if you hang the networks for your other global offices off VPNs behind one front-end site.
Are you sure about this, or have a source where I can read more? There are some counterpoints: both Japanese and Chinese use four-digit grouping for numbers, and it's common to see things like credit cards use four-digit groups.
>Variations in the amplitude of the N400 showed a better memory trace for items presented in [temporal groups] of three compared to those in groups of four.
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3959615/
This is similar to how many smaller orgs used 10.site.vlan.device but obviously it scales larger (site and vlan can each be 16 bits instead of 8) and everybody gets a unique public replacement for "10."
The prefix I get from my ISP is 56 bits long. And there's no hope of using :: in there. So yes, the public addresses are long and unmemorable.
The information content reflects that. Internal services with IPv4 are tuples of:
(public-ip, proxy-port, rfc1918-ip, actual-port)
That’s about 32 characters to type and memorize (12 + 4 + 12 + 4).
Internal services with IPv6 are tuples of:
(site-prefix, network-suffix, host-id, port)
…which for your /56 is going to be 26 characters to type and memorize (14 + 4 + 4 + 4).
E.g. 2100:db8:4032:12::431 port 123
Also looks like you are blogging about known stuff: https://isc.sans.edu/forums/diary/Correctly+Validating+IP+Ad...
https://lucb1e.com/randomprojects/php/funnip.php
https://idea.popcount.org/2019-12-06-addressing/
(a) trailing whitespace "1.2.3.4\t5" (b) link-local like %1 or %eth0
I remember seeing a very colorful page (literally) about this around 1997 and it totally blew my mind back then. Sadly I have no idea on how-to locate that page again.
[0] https://news.ycombinator.com/item?id=20390759
[1] https://news.ycombinator.com/item?id=25545967
Note that this is also nice for loopback addresses. Normally the loopback interface owns all addresses in the 127.0/8 subnet, so you can listen on any address from 127.1 to 127.16777214.
[0] EDIT: looking into this, it seems that they "fixed" it at some point but then reverted the fix for legacy reasons: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865992
https://news.ycombinator.com/item?id=18407173
I really want this convention to die.
Octal was a thing in the past, but is really seldomly used nowadays, in my impression.