Pergunta

Eu tive esse problema em minha mente última alguns dias, e eu estou lutando para frase minha pergunta.No entanto, eu acho que eu tenho pregado o que eu quero saber.

Por que o c# aceitar a imprecisão usando pontos flutuantes para armazenar dados?E qual é a vantagem de usá-lo em relação a outros métodos?

Por exemplo, Math.Pow(Math.Sqrt(2),2) não é exato em c#.Existem linguagens de programação que podemos calcular exatamente (por exemplo, o Mathematica).

Um argumento que eu poderia pensar é que o cálculo é, exatamente, é muito mais lento do que apenas lidar com a imprecisão, mas o Mathematica & Matlab são usados para calcular a gigantesca de problemas científicos, então eu acho que é difícil acreditar que essas línguas são muito significativamente mais lento do que o c#.

Então, por que é, então?

PS:Me desculpe por envio de spam, você com essas perguntas, você já sido realmente útil

Foi útil?

Solução

Por que o c# aceitar a imprecisão usando pontos flutuantes para armazenar dados?

"C#" não aceitar a compensação do desempenho ao longo do rigor;os usuários fazem, ou não, aceitar isso.

C# tem três tipos de ponto flutuante - float, double e decimal - porque esses três tipos de atender à grande maioria das necessidades do mundo real programadores.

float e double são boas para "científico" cálculos onde uma resposta que é correto para três ou quatro casas decimais é sempre perto o suficiente, porque essa é a precisão que a medida original veio com.Suponha que você divida 10.00 por 3 e obter 3.333333333333.Desde que a medida original foi provavelmente precisas de apenas 0,01, o fato de que o resultado calculado é fora por menos de 0.0000000000004 é irrelevante.Em cálculos científicos, vocês não representam conhecida-para-ser-quantidades exatas. Imprecisão na décima casa decimal é irrelevante se a medida original valor só foi preciso para a segunda casa decimal.

Este é, naturalmente, não é a verdade de cálculos financeiros.Os operandos para um cálculo financeiro, normalmente, são de uma precisão de duas casas decimais e representar quantidades exatas.Decimal é bom para o "financeiro" cálculos porque decimal resultados da operação são exata desde que todas as entradas e saídas podem ser representados exatamente como números decimais (e eles estão todos em uma faixa razoável).Casas decimais ainda tem erros de arredondamento, é claro, mas as operações que são exatos são precisamente aquelas que você provavelmente deseja para ser mais exato, quando estiver fazendo cálculos financeiros.

E qual é a vantagem de usá-lo em relação a outros métodos?

Você deve indicar o que os outros métodos que você gostaria de comparar.Há um grande número de diferentes técnicas para a realização de cálculos em computadores.

Por exemplo, a Matemática.Pow(Matemática.Sqrt(2),2) não é exata em c#.Existem linguagens de programação que podemos calcular exatamente (por exemplo, o Mathematica).

Vamos ser claros sobre este ponto;O Mathematica não "calcular" raiz de 2 exatamente;o número é irracional, então ele não pode ser calculada exatamente, em qualquer quantidade finita de armazenamento.Em vez disso, o que mathematica não é ele representa os números como objetos que descrevem como o número foi produzido.Se você disser "dá-me a raiz quadrada de dois", em seguida, Mathematica, essencialmente, aloca um objeto que significa "a aplicação da raiz quadrada do operador para o exato número 2".Se você, em seguida, a praça, que tem a finalidade especial de lógica que diz que "se você quadrado de algo que foi a raiz quadrada de outra coisa, de dar de volta o valor original".O Mathematica possui objetos que representam vários números especiais também, como pi ou e, e um enorme corpo de regras para a forma como várias manipulações de que esses números se combinam.

Basicamente, ele é um simbólico sistema;ele manipula números da mesma forma que as pessoas fazem quando fazem o lápis-e-papel de matemática.A maioria dos programas de computador manipular números como uma calculadora:executar o cálculo de imediato e arredondar-se.Se isso não é aceitável, em seguida, você deve manter um sistema simbólico.

Um argumento que eu poderia pensar é que o cálculo é, exatamente, é muito mais lento do que apenas lidar com a imprecisão, mas o Mathematica & Matlab são usados para calcular a gigantesca de problemas científicos, então eu acho que é difícil acreditar que essas línguas são muito significativamente mais lento do que o c#.

Não é que eles são mais lentos, embora a multiplicação de pontos flutuantes realmente é incrivelmente rápido em hardware moderno.É que o simbólico mecanismo de cálculo é imensamente complexo.Ele codifica todas as regras básicas de matemática, e há um monte dessas regras!C# não se destina a ser uma categoria profissional de computação simbólica do motor, ele é destinado a ser um propósito geral de uma linguagem de programação.

Outras dicas

Uma palavra:desempenho.Aritmética de ponto flutuante é normalmente implementado em hardware e é muitas ordens de magnitude mais rápido do que outras abordagens.

O que é mais seu exemplo de MATLAB é falso.O MATLAB usa double ponto flutuante de precisão aritmética assim como C#.

Por que o c# aceitar a imprecisão usando pontos flutuantes para armazenar dados?

Desta forma, suporte a ponto flutuante pode mapa para o modo de suporte de hardware pontos flutuantes, que é mais ou menos a única forma de tirar partido de operações de ponto flutuante em hardware, o que é muito mais rápido do que uma solução de software.A desvantagem é o hardware representa os pontos flutuantes com um número finito de bits, o que leva a imprecisão (note que a imprecisão é bem definido).

Outras formas de representar valores de ponto flutuante precisa de uma solução de software, é significativamente mais lento e requer mais espaço."Qualquer pessoa" pode implementar isso com o que está disponível em c#, incluindo nativo de ponto flutuante de apoio para o hardware disponível, seria muito difícil para "alguém" se isso não era já suportado na língua/CLR.

Para a maioria dos problemas de programação, a imprecisão não é um problema e float (ou double tipos de dados são bons o suficiente.Muitos anos atrás, não havia tal coisa como "valores de ponto flutuante" e de um software para armazenar valores como dois números inteiros.E o desempenho foi um problema (para não mencionar os erros de programação--wtf e cenários-do feito em ponto flutuante funções de cálculo).Assim, uma convenção foi projetado e, logo depois, os computadores eram equipados com FPUs.

Agora, quando usar o FPU para cálculos ou através de outros matemáticos librairies/programas (como o Mathematica) depende do problema.Por exemplo, o cálculo de vértices em um ambiente 3d, prefere o desempenho ao longo de precisão.Mas o software de contabilidade é diferente.Nesse aspecto, ambos problema diferente;um software de contabilidade, não será necessário calcular números complexos milhões de vezes por segundos :) (editar:ou se faz, alguns muito caros hardware irá, provavelmente, ser parte da equação também!)

Se você sei que você vai estar fazendo Matemática.pow(Matemática.sqrt(2),2) em seguida, você deve repensar a maneira de armazenar tanto valores (como o recálculo de cada vez).Este não é um problema com a linguagem de programação, mas mais um problema conceitual.

C# e a maioria de todos os outros idiomas (exceto as específicas, como Matlab) armazenar números de ponto flutuante fixa-campos de tamanho (6 ou 8 bytes), o que leva a imprecisão.

Uma razão é que o número e formatos de número são inequívocas e universal.Sim, existem erros de arredondamento, mas eles são constantes e previsíveis.Tentando configurar um formato geral para qualquer algorítmico problema não é trivial.

Há um pouco de uma explicação aqui para o mathematica

A versão curta é para regular o dia-a-dia de matemática de ponto flutuante, o hardware pode fazê-lo rapidamente com um montante conhecido de imprecisão.Então, se o seu cálculo não depender de ser mais preciso, em seguida, fazê-lo da maneira rápida.

Se você precisa de precisão, em seguida, o programador tenha de escrever o algoritmo para o grau de precisão exigido.Que vai ser mais lento.

Eu não acho que é c# problema.c# é uma linguagem de propósito geral e dá-lhe tipos de dados básicos para jogar com.Se você não está feliz com eles, você está sempre livre para criar o seu próprio.

Além disso c# não é aquele que aceitar imprecisão.Programador faz.Para grande conjunto de problemas de imprecisão é aceitável.Float não deve ser usado quando exata resultado é o esperado, mas isso é decisão para o programador não para o idioma de designer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top