2010-02-11 23 views
6

Czy ktoś może rzucić światło na to, dlaczego widzę bardzo małe różnice (10^-08) przy użyciu dokładnie takich samych liczb w Excelu i C# ??Excel Vs C# Różnice liczbowe

Mam formułę i używam tych samych danych wejściowych. W programie Excel otrzymuję jedną liczbę - w języku C# otrzymuję inną. Różnica jest niewielka.

Używam podwójnych w C# i robi podział. Próbowałem używać ułamków dziesiętnych, które nie robiły wielkiej różnicy

EDYCJA: To mnie napędza NUTY - ja spędziłem cały ranek na tym - Jakieś pomysły?

+0

Myślę, że podobne pytanie zostało zadane wcześniej ... –

+0

Każdy pomysł gdzie? –

Odpowiedz

2

Różnica wynika z różnych reguł zaokrąglania midpoint w językach C# i excel.

Spróbuj Math.Round(someNumber,precision,MidpointRounding.AwayFromZero);

2

Przy takich małych wielkości różnicy (10^-08, to stwierdzić), podejrzewam, że obliczenia pośrednie są przyczyną problemu. Zauważ, że wartości podwójnej precyzji są 64-bitowe, ale rejestry mogą pracować z 80-bitową precyzją. Tak więc, jeśli posiadasz sekwencję kodu, w której kompilator zachowa wszystkie swoje pośrednie obliczenia w rejestrach, faktycznie uzyskasz lepszą dokładność niż w przypadku, gdy te same obliczenia są wykonywane w różnych punktach kodu, co zmusza do utrzymania wyników pośrednich w 64 lokalizacje bitowe.

Jeśli w ramach obliczeń zostaną zapisane wartości w komórkach Excela, spowoduje to również obcięcie obliczeń pośrednich do 64 bitów dokładności.

Naprawdę potrzebujesz pokazać swój kod: pokaż zarówno (a) obliczenia w programie Excel (czy jest to formuła arkusza roboczego czy robisz programowe przypisania do wartości komórek?) I (b) obliczenia C#, które robisz. Jeśli to zrobisz, powinniśmy być w stanie ci pomóc bardziej precyzyjnie. Ale dzięki informacjom, które dotychczas przekazałeś, możemy tylko zgadywać.

- Mike

0

Temat ten doprowadził mnie do szału przedtem =).

Kilka lat temu odkryłem, że funkcja arkusza kalkulacyjnego Excela o nazwie =ROUND() ma inne wyniki niż funkcja VBA ROUND(). Odkryłem także, że VBA i MySQL w wersji 4.x (nie pamiętam dokładnej wersji, przed 5.x) użyły dokładnie tego samego algorytmu do zaokrąglania liczb zmiennoprzecinkowych. Wydawało się, że używają wadliwej wersji "zaokrąglania bankiera". MySQL ostatecznie zmienił swoje zaokrąglenie w przyszłych wersjach, ale ktoś zwrócił uwagę, że podobieństwo między sposobem, w jaki VBA i MySQL 4.x zaimplementowano ROUND, było prawdopodobnie spowodowane tym, że obydwa polegają na sposobie, w jaki język programowania C (prawdopodobnie używany do tworzenia VBA i MySQL) zaimplementował rundę.

Zarówno VBA, jak i MySQL 4.x po prostu zaimplementowały to, co C użyte do zaimplementowania zaokrąglenia. Jednak wiele współczesnych języków programowania wybrało zastosowanie własnych metod zaokrąglania z różnych powodów; Czasami jest to zgodne ze specyfikacją IEEE, a czasami jest zgodne z oczekiwaniami użytkowników. W przypadku VBA i MySQL 4.x użytkownik nigdy nie oczekiwał błędnej wersji zaokrąglania bankiera (stąd twoja frustracja), więc przyszłe języki wprowadziły nowe wersje zaokrąglania lub dostarczyły alternatywy (takie jak decimal w C#), więc że użytkownik będzie w stanie wytwarzać oczekiwane wartości i mieć większą kontrolę nad całym procesem.

Mógłbyś spróbować patrząc na ten artykuł do dalszego wyjaśnienia na ten temat w odniesieniu do zaokrąglania VBA za: http://www.vb-helper.com/howto_round_to_specified_digits.html

0

Czy na pewno widzisz cały numer w programie Excel?

Numery sformatowane jako "Ogólne" będą wyświetlane z dokładnością ~ 12 cyfr (lub mniej, jeśli kolumna nie jest wystarczająco szeroka dla ~ 12 cyfr). Na przykład, jeśli wstawisz formułę "= PI()" do komórki z formatem "Ogólne" (domyślnie w Excelu) i ustawisz kolumnę wystarczająco szeroko, zobaczysz 3.141592654. Zwróć uwagę, że jeśli kolumna nie jest wystarczająco szeroka, zobaczysz jeszcze mniej cyfr precyzji.

Teraz sformatuj komórkę z niestandardowym numerem "0.00000000000000000", a zobaczysz 3.14159265358979000 (jeśli kolumna jest wystarczająco szeroka).

Należy zauważyć, że Excel faktycznie przechowuje wartość = PI() wewnętrznie z więcej niż 15 cyframi precyzji. Możesz to zobaczyć, wpisując "= (PI() - 3.14159265358979)" w komórce - pamiętaj o włączeniu nawiasu w formułę.

Teraz dla zabawy wpisz "= PI() - 3.14159265358979" w komórce, a zobaczysz, że otrzymujesz zero. W niektórych przypadkach, takich jak dodawanie lub odejmowanie, gdy wynik jest "prawie zerowy", Excel faktycznie przekształci wynik na 0.0 (to może doprowadzić cię do szału, jeśli nie wiesz, że to się dzieje).