Why Are Doubles Printed Differently in Dictionaries

Why are doubles printed differently in dictionaries?

As already mentioned in the comments, a Double cannot store
the value 1.1 exactly. Swift uses (like many other languages)
binary floating point numbers according to the IEEE 754
standard.

The closest number to 1.1 that can be represented as a Double is

1.100000000000000088817841970012523233890533447265625

and the closest number to 2.3 that can be represented as a Double is

2.29999999999999982236431605997495353221893310546875

Printing that number means that it is converted to a string with
a decimal representation again, and that is done with different
precision, depending on how you print the number.

From the source code at HashedCollections.swift.gyb one can see that the description method of
Dictionary uses debugPrint() for both keys and values,
and debugPrint(x) prints the value of x.debugDescription
(if x conforms to CustomDebugStringConvertible).

On the other hand, print(x) calls x.description if x conforms
to CustomStringConvertible.

So what you see is the different output of description
and debugDescription of Double:

print(1.1.description) // 1.1
print(1.1.debugDescription) // 1.1000000000000001

From the Swift source code one can see
that both use the swift_floatingPointToString()
function in Stubs.cpp, with the Debug parameter set to false and true, respectively.
This parameter controls the precision of the number to string conversion:

int Precision = std::numeric_limits<T>::digits10;
if (Debug) {
Precision = std::numeric_limits<T>::max_digits10;
}

For the meaning of those constants, see std::numeric_limits:

  • digits10 – number of decimal digits that can be represented without change,
  • max_digits10 – number of decimal digits necessary to differentiate all values of this type.

So description creates a string with less decimal digits. That
string can be converted to a Double and back to a string giving
the same result.
debugDescription creates a string with more decimal digits, so that
any two different floating point values will produce a different output.

Why does double backslash not work in python dictionary

How do you verify that it does not work?
Using the print function you can see that it does exactly what you expect:

x = {
'myserver' : {
'DSN': 'servername',
'DATABASE': 'mydatabase',
'UID': 'myusername',
'PWD': 'my\\password'
}
}

print(x)

print(x['myserver']['PWD'])

Outputs:

{'myserver': {'DSN': 'servername', 'DATABASE': 'mydatabase', 'UID': 'myusername', 'PWD': 'my\\password'}}

and

my\password

Trying to add data to different dictionaries and print one then another

A few different problems here. First, what is your dict named (dict isn't instantiated anywhere that I can see)? You don't define it as far as I can see. As for update, the parameter is not a string and there's no reason to use format; the keys in the object can be strings, which is likely why you're confused, but those commas aren't wrapped in a string. I also don't see why you're using update here rather than just setting the properties values in general.

Finally, as with the other comments, I'm also not clear on what you want the dict to look like after, or why you'd separate highs and lows into separate dictionaries.

I'd probably do this:

def readTempData(filename):
with open(filename, 'r') as f:
data = {}
for line in f.readlines():
day, high, low = line.split(',')
high = int(high)
low = int(low)
day = int(day)
data[day] = {'high': high, 'low': low}
print(data)

readTempData(input("Enter file name:"))


You then can see the day as the key, with the high and low on the day easily accessible. If you want a seperate dict of high / low, you should clarify what you want as a key. You could also use a list of dictionaries which contain the day, high, and low.

For example, to access the high temperature on day 3:

data[3]['high']

Strange output for same Double value

As in answer explained by @MartinR, Why are doubles printed differently in dictionaries?

It is clear that 1.1200000000000001, is the double precision value of 1.12.

While you are trying to print foo object, print(foo) object is getting printed along with its enclosed information in which number holds the double precisied value of 1.21

Whereas, when you directly print(foo.number), then string representation of foo.number is getting printed which is actually 1.21

How to create a double dictionary in Python?

You could try this:

In [17]: results = {}

In [18]: for k, v in names.iteritems():
results[k] = {v: dates.setdefault(k, '')}
....:
....:

In [20]: results
Out[20]:
{'George': {'march': '21/02'},
'Mary': {'february': '2/02'},
'Peter': {'may': ''},
'Steven': {'april': '14/03'},
'Will': {'january': '7/01'}}

And as to your comment regarding adding month and day, you can add them similarly:

In [28]: for k, v in names.iteritems():
results[k] = {'month': v, 'day': dates.setdefault(k, '')}
....:
....:

In [30]: results
Out[30]:
{'George': {'day': '21/02', 'month': 'march'},
'Mary': {'day': '2/02', 'month': 'february'},
'Peter': {'day': '', 'month': 'may'},
'Steven': {'day': '14/03', 'month': 'april'},
'Will': {'day': '7/01', 'month': 'january'}}

And if you want to omit day completely in the case where a value doesn't exist:

In [8]: results = {}

In [9]: for k, v in names.iteritems():
...: results[k] = {'month': v}
...: if dates.has_key(k):
...: results[k]['day'] = dates[k]
...:
...:

In [10]: results
Out[10]:
{'George': {'day': '21/03', 'month': 'march'},
'Mary': {'day': '2/02', 'month': 'february'},
'Peter': {'month': 'may'},
'Steven': {'day': '14/03', 'month': 'april'},
'Will': {'day': '7/01', 'month': 'january'}}

And in the odd case where you know the date but not the month, iterating through the set of the keys (as @KayZhu suggested) with a defaultdict may be the easiest solution:

In [1]: from collections import defaultdict

In [2]: names = {'Will': 'january', 'Mary': 'february', 'George': 'march', 'Steven': 'april', 'Peter': 'may'}

In [3]: dates = {'Will': '7/01', 'George': '21/03', 'Steven': '14/03', 'Mary': '2/02', 'Marat': '27/03'}

In [4]: results = defaultdict(dict)

In [5]: for name in set(names.keys() + dates.keys()):
...: if name in names:
...: results[name]['month'] = names[name]
...: if name in dates:
...: results[name]['day'] = dates[name]
...:
...:

In [6]: for k, v in results.iteritems():
...: print k, v
...:
...:
George {'day': '21/03', 'month': 'march'}
Will {'day': '7/01', 'month': 'january'}
Marat {'day': '27/03'}
Steven {'day': '14/03', 'month': 'april'}
Peter {'month': 'may'}
Mary {'day': '2/02', 'month': 'february'}

C# Dictionary takes duplicate Keys / can't find Keys when calculated

Thanks to great help, I found out that double is really imprecise and might carry decimal places that won't show up because of internal rounding errors.
If you google for something like "issue with double error" or "double precision issue", you will find many who tried to solve it by writing custom methods to round the doubles by parsing them or the like. Many suggest to use decimal instead.
In my case, the single one thing that worked is converting the price / key double to an integer and then dividing it by the number of decimal places when needed.

Here a Wikipedia link about the why.



Related Topics



Leave a reply



Submit