Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产成人综合网,在线观看亚洲天堂,亚洲一区中文字幕

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          javascript中如何解決精度丟失問題

          javascript中如何解決精度丟失問題

          項(xiàng)目開發(fā)中,你一定遇到過精度丟失的問題!比如某個無良的后端返回了一個超16位的數(shù)字訂單號,比如0.1+0.2 !=0.3等等:

          let a=0.1235678912345623456
          console.log(a)
          let b=256.1235678912345623456
          console.log(b)
          let c=0.1
          let d=0.2
          console.log(c + d)
          let e=2.55
          let f=1.55
          console.log(e.toFixed(1))
          console.log(f.toFixed(1))



          01

          精度丟失的原因

          是什么原因造成的捏?

          嗯?

          大道理咱也不會說,問就是一句話回復(fù):

          在十進(jìn)制轉(zhuǎn)二進(jìn)制的過程中,因js存儲位數(shù)有限制,末位就會0舍1入取近似值,從而導(dǎo)致再轉(zhuǎn)回十進(jìn)制時產(chǎn)生誤差。



          02

          如何解決


          • 使用toPrecision;
          • 乘以10的N次冪轉(zhuǎn)換成整數(shù),再除以N次冪轉(zhuǎn)回小數(shù);
          • 先加上1e-14或Number.EPSILON再取值;
          • 使用第三方庫,處理大數(shù)的 bignumber.js,處理小數(shù)的number-precision 和 decimal.js,處理JSON序列化json-bigint。

          使用toPrecision


          這個方法主要用于純展示。先用toPrecision保留一定位數(shù)的經(jīng)度,再通過parseFloat展示。

          例如:

          console.log(parseFloat(0.30000000000000004.toPrecision(12)))

          這個12是精度默認(rèn)值或者說是一個經(jīng)驗(yàn)值,12位一般都能解決0000...1和0000...9的問題。一般不適合浮點(diǎn)數(shù)的運(yùn)算。


          先轉(zhuǎn)整數(shù)進(jìn)行運(yùn)算,再轉(zhuǎn)成小數(shù)


          這種方式是我之前浮點(diǎn)運(yùn)算時經(jīng)常用到的方法。我們拿0.1+0.2的運(yùn)算來舉例:

          let a=(0.1*10 + 0.2*10) / 10
          console.log(a) //0.3

          但這種方法也不是萬能的,有時候也會失精:

          console.log(33.41*100) //3340.9999999999995
          console.log(2.55*100)  //254.99999999999997

          真是防不勝防啊!這時候我們也可以使用Math.round()方法來達(dá)到我們的目的,如下:

          console.log(Math.round(33.41*100))  //3341
          console.log(Math.round(2.55*100))  //255
          console.log((Math.round(0.1*10) + Math.round(0.2*10)) / 10)  //0.3

          先加上1e-14或Number.EPSILON再取值


          給浮點(diǎn)數(shù)加上一個極小的數(shù)就可以達(dá)到目的。獲取極小的數(shù)有兩種方式:

          • 1e-14(10的-14次方)
          • ES6的極小的常量Number.EPSILON


          先來看看Number.EPSILON是什么?

          console.log(Number.EPSILON)  //2.220446049250313e-16
          console.log(Number.EPSILON.toFixed(20))  //0.00000000000000022204

          這兩種方式都可以,看自己的喜好啦!

          let a=0.1235678912345623456
          console.log((a+1e-14).toFixed(1)) //0.1
          console.log((0.1 + Number.EPSILON + 0.2 + Number.EPSILON).toFixed(1))
          //0.3

          第三方庫

          第三方庫主要介紹以下四種:

          • bignumber.js的使用-處理大數(shù)

          安裝:

          npm install --save bignumber.js

          引入:

          import BigNumber from 'bignumber.js';

          使用:

          const a=new BigNumber(0.2);
          const b=new BigNumber(0.1)
          let c=a.plus(b)
          console.log(c) //BigNumber {s: 1, e: -1, c: Array(1)}
          console.log(c.toString())  //0.3
          console.log(c.toNumber())  //0.3

          官網(wǎng):https://mikemcl.github.io/bignumber.js/


          • number-precision的使用-處理小數(shù)

          安裝:

          npm install number-precision --save

          引入:

          import NP from 'number-precision';

          使用:

          console.log(NP.strip(0.09999999999999998)); // 四舍五入:=0.1
          console.log(NP.round(0.105, 2)) //取2位小數(shù),四舍五入:=0.11
          console.log(NP.plus(2.3, 2.6)); // 加:=4.9
          console.log(NP.minus(1.0, 0.9)); // 減:=0.1
          console.log(NP.times(3, 0.3)); // 乘:=0.9
          console.log(NP.divide(0.9, 0.3)); // 除:=3
          console.log(NP.plus(0.1, 0.2))


          • number-precision的使用-處理小數(shù)

          安裝:

          npm install --save decimal.js

          引入:

          import Decimal from "decimal.js"

          使用:

          console.log(Decimal(0.1).add(Decimal(0.2))); // 加: {s: 1, e: -1, d: Array(1), constructor: ?}
          console.log(Decimal(0.1).sub(Decimal(0.2))); // 減:{s: -1, e: -1, d: Array(1), constructor: ?}
          console.log(Decimal(0.1).mul(Decimal(0.2))); // 乘:{s: 1, e: -2, d: Array(1), constructor: ?}
          console.log(Decimal(0.1).div(Decimal(0.2))); // 除:{s: 1, e: -1, d: Array(1), constructor: ?}

          上面的結(jié)果是Decimal 對象,取值需要Number 或 String轉(zhuǎn)換

          官網(wǎng):http://mikemcl.github.io/decimal.js/


          • json-bigint的使用-處理后端的返回值

          安裝:

          npm install json-bigint

          引入:

          import JSONBigInt from 'json-bigint';
          const JSONBigIntNative=JSONBigInt();

          使用:

          let json="{\"order\":258431607934229718,\"price\":1.258431607934229718,\"no\":123456}"
          const obj1=JSON.parse(json)
          const obj2=JSONBigIntNative.parse(json)
          console.log(obj1) //{order: 258431607934229730, price: 1.2584316079342297, no: 123456}
          console.log(obj2.order.toString())  //258431607934229718
          console.log(obj2.price.toString())  //1.258431607934229718
          console.log(obj2.order.toNumber())  //258431607934229730
          console.log(obj2.price.toNumber())  //1.2584316079342297

          主要是把大數(shù)據(jù)轉(zhuǎn)成字符串。其實(shí)關(guān)于這一點(diǎn),如果后端經(jīng)驗(yàn)豐富的話,自然會給前端返回字符串,也無需前端轉(zhuǎn)換。不過呢,可能前端的技能的提升也就是從無經(jīng)驗(yàn)的后端開始的噢!

          oundation 可以很簡單的創(chuàng)建一個提醒框:

          提醒框可以使用 .alert-box 類創(chuàng)建, 可以添加可選的類: .secondary, .success, .info, .warning.alert:

          實(shí)例

          <div data-alert class="alert-box">

          This is a default alert box.

          </div>

          <div data-alert class="alert-box secondary">

          This is a secondary alert box.

          </div>

          <div data-alert class="alert-box success">

          <strong>Success!</strong> This alert box indicates a successful or positive action.

          </div>

          <div data-alert class="alert-box info">

          <strong>Info!</strong> This alert box indicates a neutral informative change or action.

          </div>

          <div data-alert class="alert-box warning">

          <strong>Warning!</strong> This alert box indicates a warning that might need attention.

          </div>

          <div data-alert class="alert-box alert">

          <strong>Alert!</strong> This alert box indicates a dangerous or potentially negative action.

          </div>


          圓角提醒框

          .radius.round 類用于為提醒框添加圓角:

          實(shí)例

          <div data-alert class="alert-box success radius">

          <strong>Success!</strong> Alert box with a radius.

          </div>

          <div data-alert class="alert-box info round">

          <strong>Info!</strong> Alert box that is rounded.

          </div>


          關(guān)閉提醒框

          要關(guān)閉提醒框,可以在連接或按鈕元素上添加 class="close" 類,并初始化 Foundation JS:

          實(shí)例

          <div data-alert class="alert-box">

          This is a default alert box with closing functionality.

          <a href="#" class="close">&times;</a>

          </div>

          <script>

          // Initialize Foundation JS For Functionality

          $(document).ready(function() {

          $(document).foundation();

          })

          </script>

          提醒框的寬度為容器的 100%。

          &times; (×) 是一個 HTML 字符實(shí)體表示一個關(guān)閉按鈕的圖標(biāo),而不是字母 "x"。

          /面包理想

          一轉(zhuǎn)眼已經(jīng)2018年,前端行業(yè)也風(fēng)風(fēng)雨雨地走過了10多年,網(wǎng)頁布局也從最原始的文檔變成了精彩紛呈的交互。當(dāng)我看到第四代CSS布局技術(shù)的時候,在驚嘆互聯(lián)網(wǎng)發(fā)展如此突飛猛進(jìn)的同時,不禁會有一個疑問:CSS經(jīng)歷1.0到3.0的版本變遷,最終又將走向哪里?

          今天我們就回顧一下CSS簡史和四次布局技術(shù)的躍遷。

          1.CSS簡史

          為什么我們需要回顧一下CSS簡史呢?

          1.了解過去能夠更好地預(yù)測未來,畢竟太陽底下沒有什么新鮮事。

          2.相比預(yù)測未來,通過了解CSS發(fā)展演變趨勢,能夠科學(xué)合理地評判CSS的發(fā)展,指導(dǎo)我們學(xué)習(xí)CSS的核心技術(shù),讓我們在有限的精力和時間內(nèi)學(xué)對知識,學(xué)好知識。

          那是1989年的第一場雪,比1988年來的更早一些,伯納斯·李(Tim Berners-Lee)以超人的智慧和消耗了前額無數(shù)濃密的頭發(fā)為代價發(fā)明了World Wide Web,沒有他就沒有我們今天互聯(lián)網(wǎng)相關(guān)的工作,也就沒有了這個專欄教程,請?jiān)试S我代表廣大前端致以崇高的敬意。我們先一睹大神的風(fēng)采。

          對互聯(lián)網(wǎng)之父,我只想對他說一句話,有一款洗發(fā)水增發(fā)效果挺好的,我一直用,你要不要試試?

          互聯(lián)網(wǎng)誕生了以后,最初的網(wǎng)頁僅僅是純文本,但是隨著互聯(lián)網(wǎng)的發(fā)展,大家意識到web的原始版本根本就沒有提供一種裝飾網(wǎng)頁的方法。這就好比一個嬰兒不會穿著衣服出生一樣,孩子大了,總不能裸奔吧?這個時候兩個大神提供了解決方案Pei Yaun Wei和Andreesen。

          Pei Yaun Wei說,這個好辦,我們可以給孩子穿上紙尿褲。

          Pei-Yuan Wei在1991年創(chuàng)建圖形瀏覽器 ViolaWWW ,他整合了自己提出的樣式語言到自己開發(fā)的瀏覽器中,還期望自己的樣式語法最終能成為web關(guān)于樣式的官方標(biāo)準(zhǔn)。雖然這個目標(biāo)并未達(dá)到,但是他提出的樣式語法確實(shí)為其它的一些樣式語法提供了一些靈感。

          Andreesen說,那玩意得換多麻煩,我給孩子畫一身衣服吧,當(dāng)然你懂的,最后Pei Yaun Wei的方案被采用了,但是我們還是看看Andreessen畫出來的情況有多亂。

          與此同時,Andreessen 在他開發(fā)的網(wǎng)景瀏覽器中進(jìn)行了不同的嘗試。他并沒有創(chuàng)建一種分離式的標(biāo)記語言,而是采取拓展HTML標(biāo)簽的方法來包含非標(biāo)準(zhǔn)化的HTML標(biāo)簽已達(dá)到裝飾網(wǎng)頁的目的。不幸的是,沒過多久,網(wǎng)頁就失去了所有的語義化并看起來像下面這樣混亂:

          <MULTICOL COLS="3" GUTTER="25">
           <P><FONT SIZE="4" COLOR="RED">This would be some font broken up into columns</FONT></P></MULTICOL>
          

          最終被大家采納的語言是由Hakon Wium 在 1994年 10月提出的樣式語法。它被稱為樣式層疊表,簡稱CSS,但是直到1996年的時候,CSS才演變成我們熟悉的樣子。

          html { margin-left: 2cm; font-family: "Times", serif;
          }h1 { font-size: 24px;
          }
          

          然后在1998年5月W3C發(fā)表了CSS2,緊接著一個讓我們深惡痛覺的瀏覽器誕生了!對沒錯,就是你深惡痛絕的那個萬能的IE6,2001年微軟發(fā)布了IE6,不過搞笑的是,IE6最初的出現(xiàn)確實(shí)很大程度推動了CSS發(fā)展。那時候的網(wǎng)頁已經(jīng)變成跟現(xiàn)在很接近了。

          按照常理你肯定會想,后面我就知道了,你不用說了,然后就是CSS3.0了。好吧,如果是我,我也這樣想,但是國際友人的腦回路可能跟我們不一樣,事實(shí)上,CSS3早于1999年已經(jīng)開始制訂,直到2011年6月7日,CSS 3 Color Module終于發(fā)布為W3C Recommendation。這個故事告訴我們兩件事:

          1.w3c這個組織活的真夠長,甚至比很多讀者年齡都大。

          2.不是CSS正式版發(fā)布了你才放心使用,如果等到那個時候使用,你的項(xiàng)目可能未曾綻放就枯萎了。

          細(xì)心的讀者可能會問了,CSS3正式版什么時候發(fā)布啊?另外CSS4.0什么時候發(fā)布?

          好吧,我只能告訴你隨緣吧……而且沒有CSS4.0了,也不會有CSS5.0了。

          來我們再看看國際友人的腦回路:

          簡單地說,就是從CSS3開始,CSS規(guī)范就被拆成眾多模塊(module)單獨(dú)進(jìn)行升級,或者將新需求作為一個新模塊來立項(xiàng)并進(jìn)行標(biāo)準(zhǔn)化。因此今后不會再有CSS4、CSS5這種所謂大版本號的變更,有的只是CSS某個模塊級別的躍遷。

          按照CSS工作組的說法,CSS歷史上并沒有版本的概念,有的只是“級別”(level)的概念。比如,CSS3其實(shí)是CSS Level 3,CSS2是CSS Level 2,而CSS Level 1當(dāng)然就是CSS1。每個級別都以上一個級別為基礎(chǔ)。

          大家可能說這個命名好亂啊,這事兒我只想跟你說,你就把CSS工作組當(dāng)成你女朋友就好了,她開心就好,她說的都是對的,她說啥就是啥……

          至于我們,會用就好了。

          CSS出現(xiàn)的好處就是讓結(jié)構(gòu)和表現(xiàn)分離,可以更靈活的修飾網(wǎng)頁,學(xué)習(xí)也很簡單。這里我更想說說它的不足。

          1.CSS只有一個全局的命名空間,所以是無法避免出現(xiàn)選擇器沖突的。

          2.模塊化做的不夠好,所以造成嵌套和覆蓋混亂,容易產(chǎn)生一大堆亂糟糟的樣式。

          所以現(xiàn)在CSS也在向“模塊化、JS化發(fā)展”

          不過客觀地說,CSS的出現(xiàn)確實(shí)是互聯(lián)網(wǎng)里程碑式的進(jìn)步。

          CSS其實(shí)就做了兩件事:

          1.如何布局

          2.元素怎么表現(xiàn)

          說直白一點(diǎn)就是兩件事,一個房子是蓋成兩室一廳還是三室兩廳,另一件事是精裝修。

          這里大家就會看到如果一個房子180平米隔成1個10平米的主臥170平米的廁所,你再怎么精裝修也不會是一個宜居的房間。所以布局在CSS中是極其重要的。與CSS發(fā)展簡史類似,CSS布局也經(jīng)歷了一代又一代的迭代,才成為當(dāng)前的樣子。

          接下來我們就說說CSS布局簡史。

          2.CSS布局簡史

          初代table布局

          在1997年的時候,David Siegel 改變了web,他自己研究出了一項(xiàng)網(wǎng)頁布局技術(shù),利用html中的table元素和gif圖片縫合在一起,創(chuàng)造了表格布局技術(shù),之后他就猶如一頭猛獸泛濫起來。

          優(yōu)點(diǎn):布局容易、快捷、兼容性好

          缺點(diǎn):改動不便,需要重新調(diào)整,工作量大

          由于互聯(lián)網(wǎng)網(wǎng)站越來越復(fù)雜,內(nèi)容和業(yè)務(wù)更新頻繁,所以table布局是完全不能勝任的,以至于table布局的發(fā)明人都說:

          “我把炸醬和面倒在了一起,并且沒法分開它。”

          不過這個真不是我杜撰出來的,原文:

          David Siegel:“有人說我毀掉了Web,我回答他們,的確如此。我毀掉了Web是因?yàn)槲野亚煽肆突ㄉu混合在一起卻再也不能把它們分開。我犯下了把結(jié)構(gòu)跟表現(xiàn)混合在一起的錯誤。”

          然后第二代布局技術(shù)登場了,

          CSS+div布局

          CSS+div布局總結(jié)起來有三大優(yōu)點(diǎn),

          1.省時,學(xué)習(xí)容易,寫代碼也很容易,很快,效率高

          2.省事,如果業(yè)務(wù)邏輯變了,改起來特別方便快捷

          3.省錢,代碼量少,省帶寬,適合seo

          基于這三年不難看出CSS+div布局人畜無害,人見人愛,也就不難解釋為什么被廣泛地使用成為目前主流的布局技術(shù)了。當(dāng)然了他也有缺點(diǎn):

          1.需要考慮平臺兼容性,對制作人員的技能要求較高。

          2.在移動端布局顯得有些力不從心,如未知寬高float內(nèi)部元素居中、垂直水平布局、響應(yīng)式布局等方面略顯繁瑣。

          基于此,第三代布局技術(shù)應(yīng)運(yùn)而生。

          Flex布局

          優(yōu)點(diǎn):

          1.CSS3的布局方式,可以在不使用其他框架的情況下,簡便、完整、響應(yīng)式地實(shí)現(xiàn)各種頁面布局 2.移動端布局簡直太友好

          缺點(diǎn):

          兼容性較差,IE瀏覽器版本在9.0以上,基本要10.0 對于其他瀏覽器,要求兼容性寫法

          Flex布局日漸成為移動端主流布局技術(shù),但是它是單一維度的布局,這個我會在專欄后面講到,有時候也會捉襟見肘,所以目前出現(xiàn)了第四代的布局技術(shù):

          grid布局

          因?yàn)槟壳按蟛糠譃g覽器并不支持這種技術(shù),但是它代表了網(wǎng)絡(luò)發(fā)展,這里大家保持關(guān)注就好,這里我重點(diǎn)說下它為什么可以稱為第四代網(wǎng)絡(luò)布局技術(shù)。首先一個觀點(diǎn)大家先記住:

          它并不會取代第三代的布局技術(shù),而是顛覆和突破。就好像Flex遠(yuǎn)比div+CSS布局更方便,但是div+CSS依然有用武之地。

          我們說下它的突破之處:

          1.flex對標(biāo)的是float,本質(zhì)上還是一維布局,這就跟別人開著夏利,你開奔馳都是地面上跑沒啥本質(zhì)區(qū)別一樣。但是grid升維了,grid是飛機(jī),在地面馬路這條線一維之上讓人能夠思考高度這個維度,以前是汽車一維交通工具(你只能在水平方向一個方向開),飛機(jī)是二維(能俯沖了(橫向、縱向同時)),所以grid可以說是拓寬了CSS布局的維度。不排除將來會有三維布局的出現(xiàn)。到時候CSS不僅僅能控制橫向布局,縱向布局,還可以深度布局(這個要依賴于三維展示的出現(xiàn),如VR,AR三維立體的展示設(shè)備出現(xiàn))。

          2.grid布局里面采用了“可視化布局(template部分,所見即所得)”,這個是顛覆了傳統(tǒng)的,寫一句代碼刷一下瀏覽器這樣的開發(fā)方式,不排除以后會出現(xiàn)代碼即效果的開發(fā)模式。比如你在一個設(shè)備上畫一個區(qū)域,然后畫輪播圖。

          這種方式類似于vc++控件方式,但是更智能,也更友好。誰說不可能呢?大家不要忘了grid布局的來源是早就廢棄的table布局。說到這里我多說一句搞笑的微軟,frontpage沒火,dreamwaver火了,最早提出“canvas”概念的 VML沒火,最后html5的canvas火了,連CSS3網(wǎng)格布局也是由微軟創(chuàng)建的一個模塊 ,最后火起來居然沒人認(rèn)識它。心疼微軟一秒鐘。

          說到這里大家對CSS簡史和布局也有所了解了,我們總結(jié)下,通過本文你應(yīng)該學(xué)到:

          (1)CSS的發(fā)展歷史。

          (2)熟知布局的發(fā)展歷史,以便對未來布局技術(shù)的發(fā)展有一個客觀的判斷,來選擇是否學(xué)習(xí)。

          通過本文的學(xué)習(xí)大家已經(jīng)對CSS相關(guān)基礎(chǔ)知識有所了解,接下來我們就開始真正的進(jìn)入技術(shù)的學(xué)習(xí),大家是不是迫不及待了呢?


          主站蜘蛛池模板: 成人区精品一区二区不卡亚洲| 无码国产精品一区二区免费3p| 中文字幕一区二区人妻性色| 亚洲码欧美码一区二区三区 | 乱码人妻一区二区三区| 亚洲人AV永久一区二区三区久久| 竹菊影视欧美日韩一区二区三区四区五区 | 美女视频一区二区三区| 99久久无码一区人妻a黑| 国产亚洲综合一区柠檬导航 | 国产精品区一区二区三在线播放 | 伊人激情AV一区二区三区| 色一情一乱一伦一区二区三区 | 国产无套精品一区二区| 精品国产亚洲一区二区在线观看 | 国产在线乱子伦一区二区| 人体内射精一区二区三区| 国产乱码精品一区二区三区中文| 亚洲国产成人精品久久久国产成人一区二区三区综 | 日韩精品无码一区二区视频| 色系一区二区三区四区五区| 精品在线视频一区| 日本中文字幕在线视频一区| 国产伦精品一区二区三区无广告| 少妇人妻精品一区二区| 精品国产日韩亚洲一区在线| 精品国产免费观看一区| 国产福利在线观看一区二区| 老鸭窝毛片一区二区三区 | 国内精品一区二区三区东京| 亚洲午夜一区二区三区| 一区国产传媒国产精品| 无码少妇A片一区二区三区| 精品国产亚洲一区二区三区在线观看 | 久久综合亚洲色一区二区三区| 精品无码一区在线观看| 人妻在线无码一区二区三区| av一区二区三区人妻少妇| 视频一区二区精品的福利| 亚洲国产精品一区二区第一页免| 中文字幕一区二区视频|