tag:blogger.com,1999:blog-47785525642178162732024-03-05T17:32:39.959-08:00Blog do RobsonDesbravando o mundo da programação.Robson V. Rezinihttp://www.blogger.com/profile/11332150134746774698noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-4778552564217816273.post-64003422127576916742010-09-18T09:13:00.000-07:002010-09-18T09:53:38.884-07:00Casas decimais, arredondamentos e totaisProblemas com casas decimais, arredondamentos e totais existe em muitos aplicativos, no .NET, no Excel, no Access e em muitos outros, creio até que muitos dos leitores já tiveram este tipo de problema, principalmente os que trabalham programando sistemas que envolvem algum módulo financeiro.<br />Imagine que você esteje programando uma rotina que é responsável por listar uma composição de preço de um determinado produto que é composto por outros produtos, ou seja,possui alguns itens com preços, conforme exemplo abaixo:<br /><br />Produto: Coleção Engrenagens XPTO<br /> Composição<br /> <table border="0" cellpadding="0" cellspacing="0" width="314"><col style="width: 48pt;" width="64"> <col style="width: 92pt;" width="122"> <col style="width: 48pt;" span="2" width="64"> <tbody><tr style="height: 15.75pt;" height="21"> <td class="xl68" style="height: 15.75pt; width: 48pt;" height="21" width="64">Item</td> <td class="xl69" style="border-left: medium none; width: 92pt;" width="122">Descrição</td> <td class="xl69" style="border-left: medium none; width: 48pt;" width="64">Qtd.</td> <td class="xl70" style="border-left: medium none; width: 48pt;" width="64">Valor</td> </tr> <tr style="height: 15pt;" height="20"> <td class="xl71" style="height: 15pt;" height="20">1</td> <td class="xl66" style="border-left: medium none;">Engrenagem XPTO</td> <td class="xl65" style="border-left: medium none;">1</td> <td class="xl72" style="border-left: medium none;">1,2327</td> </tr> <tr style="height: 15.75pt;" height="21"> <td class="xl73" style="height: 15.75pt; border-top: medium none;" height="21">2</td> <td class="xl67" style="border-top: medium none; border-left: medium none;">Engrenagem XPTO</td> <td class="xl74" style="border-top: medium none; border-left: medium none;">1</td> <td class="xl75" style="border-top: medium none; border-left: medium none;">1,2327</td> </tr> </tbody></table><br />Valor Total do Produto: 2,4654<br /><br />O total seria 2,4654 e arredondando seria 2,47 (Pode usar qualquer função "Round()" que você vai verificar isso).<br />Não, não é tão fácil assim como parece, imagine que o seu cliente trabalho com composição de preços com quatro casas decimais, mas ele quer que o usuário visualize somente duas casas decimais, eis aí que surge um problema.<br />Veja como ficaria a listagem:<br /><br />Produto: Motor XPTO<br /> Composição<br /> <table border="0" cellpadding="0" cellspacing="0" width="420"><col style="width: 48pt;" width="64"> <col style="width: 92pt;" width="122"> <col style="width: 48pt;" span="2" width="64"> <col style="width: 80pt;" width="106"> <tbody><tr style="height: 15.75pt;" height="21"> <td class="xl68" style="height: 15.75pt; width: 48pt;" height="21" width="64">Item</td> <td class="xl69" style="border-left: medium none; width: 92pt;" width="122">Descrição</td> <td class="xl69" style="border-left: medium none; width: 48pt;" width="64">Qtd.</td> <td class="xl69" style="border-left: medium none; width: 48pt;" width="64">Valor</td> <td class="xl75" style="border-left: medium none; width: 80pt;" width="106">Valor "Round()"</td> </tr> <tr style="height: 15pt;" height="20"> <td class="xl70" style="height: 15pt;" height="20">1</td> <td class="xl66" style="border-left: medium none;">Engrenagem XPTO</td> <td class="xl65" style="border-left: medium none;">1</td> <td class="xl65" style="border-left: medium none;">1,2327</td> <td class="xl74" style="border-left: medium none;">1,23</td> </tr> <tr style="height: 15.75pt;" height="21"> <td class="xl71" style="height: 15.75pt; border-top: medium none;" height="21">2</td> <td class="xl67" style="border-top: medium none; border-left: medium none;">Engrenagem XPTO</td> <td class="xl72" style="border-top: medium none; border-left: medium none;">1</td> <td class="xl72" style="border-top: medium none; border-left: medium none;">1,2327</td> <td class="xl73" style="border-top: medium none; border-left: medium none;">1,23</td> </tr> </tbody></table><br /><br />Valor Total do Produto: 2,4654<br />Valor Total do Produto com duas casas: 1,23 + 1,23 = 2,46<br /><br />Arredondando o Valor do produto com quatro casas: Round(2,4654) = 2,47 !!!<br />Opa! Alguma coisa deu errado! Mas o que foi? Os resultados não batem, há uma diferença de um centavo. Onde ficou esse um centavo?<br />Esse centavo ficu no arredondamento, sim, quando arredondamos o 1,2327 , perdemos 0,0027.<br />Todos já conhecem a regra de arredondamento não? Aqui na <a href="http://www.blogger.com/%28http://pt.wikipedia.org/wiki/Arredondamento%29">wikipedia </a>você encontra o seu funcionamento.<br />Como todos os aplicativos geralmente seguem essa regra de arredondamento, acabamos perdendo alguns centavos. Isso não é um problema de qualquer aplicativo ou linguagem e sim um problema da regra utilizada.<br />Mas como não podemos mudar a regra, temos que achar uma forma de trabalhar com os arredondamentos sem mostrar ao usuário o erro que é gerado, ou seja, precisamos "excluir" esses centavos a mais que o arredondamento faz.<br />Devemos então trabalhar da seguinte forma: Sempre antes de executar um cálculo que será visualizado em menos casas decimais do que os seu operadores, devemos antes, arredondar os operadores para fazer o cálculo, sendo assim, o usuário sempre vai visualizar os dados efetivos que foram calculados e não o seu arredondamento executado depois do cálculo.<br />Veja o exemplo abaixo em C#:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSn9jdbZIbVMfsUTwMsTMF0vXvUPh6BjTqyvQ8SMdIzxhEaj9mHhF_MxZJM2u1PUhyQOAHSWU1PbzoxejljmELf5BC9br5CUvKKvhtzCU1hUw8ec_0MAUnDGZss6qERzjFughmKS1whWk-/s1600/Capturar.PNG"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 423px; height: 306px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSn9jdbZIbVMfsUTwMsTMF0vXvUPh6BjTqyvQ8SMdIzxhEaj9mHhF_MxZJM2u1PUhyQOAHSWU1PbzoxejljmELf5BC9br5CUvKKvhtzCU1hUw8ec_0MAUnDGZss6qERzjFughmKS1whWk-/s400/Capturar.PNG" alt="" id="BLOGGER_PHOTO_ID_5518297128739543106" border="0" /></a>Quando arredondamos depois de fazer o cálculo para exibir para o usuário, poderá ocorrer esse erro dos centavos no arredondamento, mas se fazemos o arredondamento dos operadores antes de executar o cálculo, os dados sempre vão "bater".<br />Veja como o Excel também se perde:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEIrgKZAIFiGv-woXXeeqHwbsij00VUXtlXn3IMcupVBbIbjqGpNiSSjz1oOSMBAW5-Q5DmPTrYQQnpfq2o_uXkkRvDiSGoVNWgtLw1gHpdo6aGKPovJwkryOwEkWY88HV5CId1S5Ogl44/s1600/Sem+t%C3%ADtulo.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 154px; height: 400px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEIrgKZAIFiGv-woXXeeqHwbsij00VUXtlXn3IMcupVBbIbjqGpNiSSjz1oOSMBAW5-Q5DmPTrYQQnpfq2o_uXkkRvDiSGoVNWgtLw1gHpdo6aGKPovJwkryOwEkWY88HV5CId1S5Ogl44/s400/Sem+t%C3%ADtulo.png" alt="" id="BLOGGER_PHOTO_ID_5518297132179675458" border="0" /></a>Em resumo, sempre cheque bem os seus códigos fontes para que não ocorram problemas com os arredondamentos.Robson V. Rezinihttp://www.blogger.com/profile/11332150134746774698noreply@blogger.com0tag:blogger.com,1999:blog-4778552564217816273.post-88784445057646263722010-09-15T15:41:00.000-07:002010-09-15T16:41:58.705-07:00ASP.NET MVC 3 - Novas funções e característicaMuitas pessoas já estão se utilizando da nova versão do MVC, o MVC 3, que foi lançado recentemente. Mas que funções e características novas ele nos trás?<br />Bem, vou enumerar algumas e explicar brevemente o que elas fazem.<br /><br /><span style="font-size:130%;">Razor View Engine</span><br /><br />Talvez a mais badalada e que nos provém mais flexibilidade na hora de programar. O Razor Engine View é um novo view engine que nos provém a capacidade de programar as Views do MVC utilizando a sintaxe Razor (juntando-se agora às outras três, <a href="http://sparkviewengine.com/">Spark</a>, <a href="http://code.google.com/p/nhaml/wiki/NHamlLanguageReference">NHaml </a>e o tradicional ASPX.<br />A engine view ASPX nos leva ao clássico ASP, utilizando a sintaxe <%= %> ou a mais nova <%: %> que predominam nos deus códigos, juntos das Master Pages e os controles ASPC.<br />A engine view Spark (utilizada também no projeto MonoRail Castle) é um pouco diferente, suporta placeholders e mistura livremente HTML com código de programação, utilizando atributos e tags especiais. A vantagem dela é de ser completamente compatível com o XML.<br />A engine view NHaml é uma implementação para o .NET da linguagem d emarkup Haml, e não utiliza a síntaxe parecendo um XML. Existe ainda a possibilidade de você implementar uma <a href="http://www.singingeels.com/Articles/Creating_a_Custom_View_Engine_in_ASPNET_MVC.aspx">view engine para o mvc</a>.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNOI4mShknH01W1kwiRQnaBZiOhmCwGPvS59k6CqKSsQ7K2gQ4omZPFewk5hTIxmLDqgFKusDqygQceWaT6hK-uPPCuExaVuPLHo-XTGPutyKTZ-1K-sImj3RSE_AYIbP86R6YvIwD2Mdl/"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 570px; height: 146px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNOI4mShknH01W1kwiRQnaBZiOhmCwGPvS59k6CqKSsQ7K2gQ4omZPFewk5hTIxmLDqgFKusDqygQceWaT6hK-uPPCuExaVuPLHo-XTGPutyKTZ-1K-sImj3RSE_AYIbP86R6YvIwD2Mdl/" alt="" border="0" /></a>Mas voltando ao Razor, sua principal característica é o minimalismo, ou seja, chega daquelas páginas cheias de tags e códigos que ficam entre seu código fonte e você, poluindo toda a sua página. Com ele você consegue escrever em C#, VB.NET e HTML.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtScOSOuGTPsM2nxCc2LUK47A28gU9-wdXIzia4999pNWpVfJTFXKTPloNdKOn-URuWwIFh80lC1Kct8_LY8RNM0QOZWMlGSbENz0f-ppFtaxn-hGfRNoP8MYfUB2Y2UB1dDigswXBA-dL/s640/MVCComRazor3.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 640px; height: 494px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtScOSOuGTPsM2nxCc2LUK47A28gU9-wdXIzia4999pNWpVfJTFXKTPloNdKOn-URuWwIFh80lC1Kct8_LY8RNM0QOZWMlGSbENz0f-ppFtaxn-hGfRNoP8MYfUB2Y2UB1dDigswXBA-dL/s640/MVCComRazor3.png" alt="" border="0" /></a>Ele é compacto, fácil de aprender, não é uma linguagem nova, trabalha com qualquer editor de texto e suporta <span style="font-style: italic;">Unit Tests</span> para suas views. O MVC3 suporta somente Views em Razor que possuem a extensão cshtml e o suporte à VB virá nas próximas versões do MVC 3.<br />Nesse <a href="http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx">site </a>você poderá encotnrar mais conteúdo sobre o Razor.<br /><br /><span style="font-size:130%;">Propriedades <span style="font-style: italic;">Dynamic View</span> e <span style="font-style: italic;">ViewModel </span></span><br /><br />É uma nova propriedade dinâmica que está disponível nas Views, e nos provém acesso ao objeto ViewData utilizando uma sixtaxe simples. Por exemplo, se dois itens são adicionados ao <span style="font-style: italic;">ViewData</span> na Action <span style="font-style: italic;">Index </span>do <span style="font-style: italic;">Controller </span>da View, como no código abaixo:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWfOokFIRUoyQE0wEfbq28j7acS5rSPTw1cLyzxsHa_Uz52Lp3qT6F9CRyT-leNc7XTMKtVg2nryecAjpNZfGegtW98MlO-K3ueNoEIusiGc6cwNYZZ1dw-buE2D-7PE8a6HompuxY_UN5/s1600/MVCComRazor5.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 314px; height: 121px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWfOokFIRUoyQE0wEfbq28j7acS5rSPTw1cLyzxsHa_Uz52Lp3qT6F9CRyT-leNc7XTMKtVg2nryecAjpNZfGegtW98MlO-K3ueNoEIusiGc6cwNYZZ1dw-buE2D-7PE8a6HompuxY_UN5/s320/MVCComRazor5.png" alt="" id="BLOGGER_PHOTO_ID_5517278415035101506" border="0" /></a>Essas propriedades podem ser acessadas utilizando-se a seguinte sintaxe:<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsZbmQ245QcEqqj-qCmHmF1DqHSVUB1dnmljd6M0yiE1vrzrspRCDjDuAGE_BAsJ6fHsy9RK2SuB0W24tOEYEaqsRW8wWR_EVG2v7tZTo759cGrzGM_1LV5MVp4_AaYkd-er9gaBaA3mCc/s1600/MVCComRazor6.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 167px; height: 68px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsZbmQ245QcEqqj-qCmHmF1DqHSVUB1dnmljd6M0yiE1vrzrspRCDjDuAGE_BAsJ6fHsy9RK2SuB0W24tOEYEaqsRW8wWR_EVG2v7tZTo759cGrzGM_1LV5MVp4_AaYkd-er9gaBaA3mCc/s320/MVCComRazor6.png" alt="" id="BLOGGER_PHOTO_ID_5517278742531336354" border="0" /></a>Esta sintaxe pode ser utilizada no <span style="font-style: italic;">Controller </span>também:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRvuQo-Q8Ipoew4YHCijUcmvm4_NMKWY0dj4q2YGMUciKJ6GqoQNndaitxfBTX6CESMhyTGadRHdztqPKXtx5lRs54tx7AaoByuYS018Rbwk64g4q-LBL1e744m5ZAngQRWaaI-nI4Qlei/s1600/MVCComRazor7.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 311px; height: 127px; font-style: italic; font-weight: bold;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRvuQo-Q8Ipoew4YHCijUcmvm4_NMKWY0dj4q2YGMUciKJ6GqoQNndaitxfBTX6CESMhyTGadRHdztqPKXtx5lRs54tx7AaoByuYS018Rbwk64g4q-LBL1e744m5ZAngQRWaaI-nI4Qlei/s320/MVCComRazor7.png" alt="" id="BLOGGER_PHOTO_ID_5517279568081913986" border="0" /><span style="display: block;" id="formatbar_Buttons"><span class=" on down" style="display: block;" id="formatbar_Italic" title="Itálico"><img src="http://www.blogger.com/img/blank.gif" alt="Itálico" class="gl_italic" border="0" /></span></span></a><span style="font-size:130%;">Suporte à Multiplos View Engines na Janela "<span style="font-style: italic;">Add View</span>"</span><br /><br />A Janela de adição de Views ao projeto do Visual Studio agora dá suporte a seleção de qual Engine View você quer utilizar:<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyqNfEnT09JvFqdKFniZgbMRlKDfNbRtrEaa9wBxHsCJGjYSsoGpJBJItug5stylOQoGmYffzle2SY-ROxOmOyUmTJW42RP81G8-2V5wAnFHpA4WeLV15u2o80id3RZu0s2MSp2DKBTDPH/"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 478px; height: 472px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyqNfEnT09JvFqdKFniZgbMRlKDfNbRtrEaa9wBxHsCJGjYSsoGpJBJItug5stylOQoGmYffzle2SY-ROxOmOyUmTJW42RP81G8-2V5wAnFHpA4WeLV15u2o80id3RZu0s2MSp2DKBTDPH/" alt="" border="0" /></a><span style="font-size:130%;">Nova Classe <span style="font-style: italic;">JsonValueProviderFactory</span></span><br /><br />Essa classe permite que os Actions de um Controller recebam os dados (parâmetros) em formato JSON.<a href="http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx"> Aqui </a>você encontra mais sobre esta novidade.<br /><br /><span style="font-size:130%;">Suporte aos atributos de validação e <span style="font-style: italic;">IValidatableObject </span>do .NET Framework 4</span><br /><br />A classe <span style="font-style: italic;">ValidationAttribute </span>foi melhorada no. NET Framework 4 para permitir um suporte melhor à validação. Quando você utiliza um atributo de validação personalizado, você pode usar uma nova sobrecarga, o <span style="font-style: italic;">IsValid </span>que fornece uma instânciado objeto <span style="font-style: italic;">ValidationContext</span>. Essa instância fornece informações sobre o contecto da validação atual, como qual objeto está sendo validado.<br />Isso permite que você valide um valor de atributo corrente baseado em uma propriedade do Model. Veja o exemplo abaixo que valida se a <span style="font-style: italic;">PropriedadeUM </span>é maior que a <span style="font-style: italic;">PropriedadeDois</span>.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs26WExIAEfgw-jp_kt708gFv8r8tODUSKmvNH_Ca-KbPw8u7Sbvh5W-wYs3ZpoQu0jDHcJk6GVFXiNsDdZ4N0Zo7OWTMCXo-BGsDdAkKGkRsImtMuRBpyY_cVfxWEybaZi_-oGgy-XEXf/"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 671px; height: 219px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs26WExIAEfgw-jp_kt708gFv8r8tODUSKmvNH_Ca-KbPw8u7Sbvh5W-wYs3ZpoQu0jDHcJk6GVFXiNsDdZ4N0Zo7OWTMCXo-BGsDdAkKGkRsImtMuRBpyY_cVfxWEybaZi_-oGgy-XEXf/" alt="" border="0" /></a>A Validação do novo MVC também suporte a interface <span style="font-style: italic;">IValidatableObject </span>do .NET Framework 4. Essa interface permite que o seu Model implemente uma validação interna, em nível de Model, como este exemplo:<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp6FeNcM6pe9PGToFWxesrADvQLlgqIQemMrdw6461a6HjDG3glFVvcI5dqwK1Zm8pDT2bVf28IVRY5tmTThTTdLjKjd3NmjeK5juZSFia3JxyRMt4voiQEV-_UylqLytcdfmWJxYUaK6y/"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 633px; height: 271px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp6FeNcM6pe9PGToFWxesrADvQLlgqIQemMrdw6461a6HjDG3glFVvcI5dqwK1Zm8pDT2bVf28IVRY5tmTThTTdLjKjd3NmjeK5juZSFia3JxyRMt4voiQEV-_UylqLytcdfmWJxYUaK6y/" alt="" border="0" /></a><span style="font-size:130%;">Suporte aos Atributos de Metadata do .NET Framework 4</span><br /><br />O ASP.NET MVC 3 agora suporta Atributos de Metadados do .Net Framework 4, como o DisplayAttribute<br /><br /><span style="font-size:100%;"> Novos Action Result Types</span><br />No ASP.NET MVC 3, a classe Controller inclui agora dois novos Action Result Types.<br /><br /><span style="font-style: italic;">HttpNotFoundResult </span>Action<br />Esse novo tipo de retorno de action é utilizado para indicar quando um recurso procurado pela URL corrente não foi encontrado:<br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG447VK8-06CwnWpRpmHsOXZvrwADpIUejF0S2SEB2kTdHpe_EV180VFZuIx3dESBkYj9MRm8Fdi_MQAXh1-DDmSuxFpvE-sxpD0po9-LsyMTGrUkY2o33dFU1wusjkwGfRd3Z2BXlB-S2/s1600/MVCComRazor11.png"><img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 276px; height: 148px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG447VK8-06CwnWpRpmHsOXZvrwADpIUejF0S2SEB2kTdHpe_EV180VFZuIx3dESBkYj9MRm8Fdi_MQAXh1-DDmSuxFpvE-sxpD0po9-LsyMTGrUkY2o33dFU1wusjkwGfRd3Z2BXlB-S2/s400/MVCComRazor11.png" alt="" id="BLOGGER_PHOTO_ID_5517281451382739666" border="0" /></a><span style="font-style: italic;">HttpStatusCodeResult</span> Action<br />Esse novo tipo de retorno de action é usado para definir o código de status de resposta e descrição.<br /><br /><br />Essas são algumas características novas presentes no MVC 3. Caso queira ver todas na íntegra, você pode verificar o site do MVC <a href="http://www.asp.net/mvc">http://www.asp.net/mvc</a>.<br /><br />Você pode fazer o download do MVC 3 Preview 1 <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=cb42f741-8fb1-4f43-a5fa-812096f8d1e8&displaylang=en">aqui</a>.Robson V. Rezinihttp://www.blogger.com/profile/11332150134746774698noreply@blogger.com0