整合營銷服務(wù)商

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

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

          21html模版里的if判斷語句

          家好,html模板的判斷語句和Python里的寫法是一樣的,只不過每一行需要包裹在花括號(hào)和百分號(hào)里。

          ·從視圖函數(shù)里傳遞一個(gè)名稱為user的數(shù)據(jù),user變量的值輸入小鐵,在html文件里判斷。如果user返回了數(shù)據(jù)顯示歡迎你小鐵,否則如果沒有顯示數(shù)據(jù)顯示請(qǐng)登錄。

          ·最后用and if來閉合判斷語句,運(yùn)行Web服務(wù),在瀏覽器里查看效果。因?yàn)閡ser這個(gè)變量是有數(shù)據(jù)的,所以前端顯示的歡迎您小鐵。將user變量的值改成無,回到瀏覽器查看效果,這個(gè)時(shí)候?yàn)g覽器顯示的是請(qǐng)登錄。

          這就是html模板文件里if判斷語句的使用方法。

          譯 | 鄭麗媛
          出品 | CSDN(ID:CSDNnews)

          看到這個(gè)標(biāo)題,相信大多數(shù)人的第一反應(yīng)是:真的有人用 40 億條 if 語句,只為判斷一個(gè)數(shù)字是奇數(shù)還是偶數(shù)?的確有,這個(gè)開發(fā)者名為 Andreas Karlsson,他還把整個(gè)過程都整理成文了。

          或許由于這“40 億條 if 語句”聽起來實(shí)在震撼,Andreas Karlsson 分享的這篇文章在 Hacker News 上很快引起了極大的關(guān)注和討論,而他在文中也直白表示:其實(shí)這個(gè)想法,最初源于一個(gè)充滿惡評(píng)的短視頻。

          下為譯文:

          大于 11 的數(shù)字,沒有輸出結(jié)果

          我最近在火車上刷手機(jī)時(shí),偶然發(fā)現(xiàn)了上面這個(gè)截圖:“寫了一個(gè)程序,來判斷一個(gè)數(shù)字是偶數(shù)還是奇數(shù)。”點(diǎn)開評(píng)論區(qū),果然是一連串的惡意評(píng)論,多數(shù)都在嘲笑這位新手程序員的稚嫩和無知,竟企圖以這種方式解決計(jì)算機(jī)科學(xué)中的經(jīng)典問題“取模運(yùn)算”。

          可看過截圖中的代碼和網(wǎng)友評(píng)論后,我莫名生出了一些不同的想法:現(xiàn)在,AI 正在分分鐘取代程序員、搶走他們的飯碗,并徹底改變了我們對(duì)代碼的思考方式,或許我們應(yīng)該更加開放地接受這個(gè)行業(yè)新生代的思想?

          其實(shí)仔細(xì)想來,上述代碼是時(shí)間和空間的一種完美權(quán)衡:你在付出自己時(shí)間的同時(shí),也換來了計(jì)算機(jī)的內(nèi)存和時(shí)間——這難道不是一個(gè)神奇的算法嗎?

          于是,我開始探索這種只使用比較來判斷一個(gè)數(shù)字是奇數(shù)還是偶數(shù)的想法,看看它在實(shí)際情況中的效果到底如何。由于我是一位高性能代碼的忠實(shí)擁護(hù)者,因此我決定用 C 語言來實(shí)現(xiàn)這個(gè)想法。

          然后,我就開始編碼了:

          • /* Copyright 2023. All unauthorized distribution of this source code  will be persecuted to the fullest extent of the law*/#include <stdio.h>#include <stdint.h>#include <stdlib.h>int main(int argc, char* argv[]){ uint8_t number = atoi(argv[1]); // No problems here if (number == 0) printf("even\n"); if (number == 1) printf("odd\n"); if (number == 2) printf("even\n"); if (number == 3) printf("odd\n"); if (number == 4) printf("even\n"); if (number == 5) printf("odd\n"); if (number == 6) printf("even\n"); if (number == 7) printf("odd\n"); if (number == 8) printf("even\n"); if (number == 9) printf("odd\n"); if (number == 10) printf("even\n");}

            接下來,我們要編譯這段代碼,使用 /Od 禁用優(yōu)化,確保煩人的編譯器不會(huì)干擾我們的算法。編譯完成后,我們就可以對(duì)程序進(jìn)行快速測(cè)試,看看結(jié)果如何:

            • PS > cl.exe /Od program.cPS > .\program.exe 0 evenPS > .\program.exe 4evenPS > .\program.exe 3oddPS > .\program.exe 7odd

              結(jié)果顯示:0、4 是偶數(shù),3、7 是奇數(shù)。這么看來,程序似乎運(yùn)行得挺好,但在進(jìn)一步測(cè)試后,我發(fā)現(xiàn)了一些問題:

              • PS > .\program.exe 50PS > .\program.exe 11PS > .\program.exe 99

                大于 11 的數(shù)字沒有輸出,看來這個(gè)程序只對(duì) 11 以下的數(shù)字有效!回到原始代碼中,可以發(fā)現(xiàn)問題出在最后一個(gè) if 語句之后:我們需要更多的 if 語句!

                向 32 位(32-bit)數(shù)擴(kuò)展

                這件事進(jìn)行到這里,就需要我在時(shí)間和內(nèi)存之間做出權(quán)衡了。考慮到我的壽命有限,我決定用另一種編程語言對(duì) if 語句進(jìn)行元編程。為了彌補(bǔ)這種“作弊”行為,我決定用“地球上速度最慢”的語言 Python。

                • print("/* Copyright 2023. All unauthorized distribution of this source code")print(" will be persecuted to the fullest extent of the law*/")

                  print("#include <stdio.h>")print("#include <stdint.h>")print("#include <stdlib.h>")

                  print("int main(int argc, char* argv[])")print("{")print(" uint8_t number = atoi(argv[1]); // No problems here")

                  for i in range(2**8): print(" if (number == "+str(i)+")") if i % 2 == 0: print(" printf(\"even\n\");") else: print(" printf(\"odd\n\");")

                  print("}")

                  好了!現(xiàn)在我們可以生成一個(gè)程序,解決所有 8 位(8-bit)整數(shù)的奇偶問題!

                  • PS > python programmer.py > program.cPS > cl.exe /Od program.cPS > .\program.exe 99oddPS > .\program.exe 50evenPS > .\program.exe 240evenPS > .\program.exe 241odd

                    看看,這個(gè)效果簡(jiǎn)直完美!現(xiàn)在,讓我們把它放大到 16 位(16-bit)!

                    • print(" uint16_t number = atoi(argv[1]); // No problems here")for i in range(2**16):

                      這樣就得到了一個(gè)約 13 萬行、超長且漂亮的 c 文件。回顧了一下我多年工作所做的一些代碼庫,這其實(shí)不算什么。話不多說,開始編譯!

                      • PS > python programmer.py > program.cPS > cl.exe /Od program.cPS > .\program.exe 21000evenPS > .\program.exe 3475 oddPS > .\program.exe 3 oddPS > .\program.exe 65001oddPS > .\program.exe 65532even

                        太棒了,我們的算法似乎能夠處理大量數(shù)據(jù)!可執(zhí)行文件大約只有 2 MB,但這與我擁有高達(dá) 31.8 GB 內(nèi)存的強(qiáng)大游戲設(shè)備相比,簡(jiǎn)直不值一提。

                        但眾所周知,32 位(32-bit)才是計(jì)算機(jī)領(lǐng)域的終極目標(biāo),也是我們解決所有實(shí)際工程和科學(xué)問題所需的最終位寬。畢竟,在 IPv4 因所謂的 "地址耗盡 "而被認(rèn)為過時(shí) 60 年后,它如今仍然很強(qiáng)大。所以,讓我們來看看最終的規(guī)模:32 位的數(shù)字是 16 位的 65536 倍,這會(huì)有什么問題嗎?

                        • print(" uint32_t number = atoi(argv[1]); // No problems here")for i in range(2**32):

                          于是,我讓強(qiáng)大的 Python 開始它的工作。48 小時(shí)后,我喝了一杯咖啡,然后回來檢查程序,就得到了一個(gè)美麗的 c 文件,大小接近 330 GB!我?guī)缀蹩梢钥隙ǎ@是歷史上最大的 c 文件之一。當(dāng)我輸入下一條命令時(shí),我的手指都在顫抖,我猜 MSVC 肯定從未遇到如此強(qiáng)大的源代碼。

                          在我那臺(tái)可憐而強(qiáng)大的電腦頁面文件中遭受半小時(shí)的折磨后,輸出如下:

                          • PS > cl /Od program.cMicrosoft (R) C/C++ Optimizing Compiler Version 19.32.31329 for x64Copyright (C) Microsoft Corporation. All rights reserved.

                            program.cprogram.c(134397076): warning C4049: compiler limit: terminating line number emissionprogram.c(134397076): note: Compiler limit for line number is 16777215program.c(41133672): fatal error C1060: compiler is out of heap space

                            太令人失望了!不僅編譯器讓我失望,在研究 Windows 可移植可執(zhí)行文件格式(.exe)的限制時(shí),我發(fā)現(xiàn)它無法處理超過 4GB 的文件!由于需要將 40 多億次比較語句編碼到可執(zhí)行文件中,這對(duì)于實(shí)現(xiàn)我們的算法是一個(gè)主要障礙。即使每次比較時(shí)使用的字節(jié)數(shù)少于一個(gè),對(duì)我來說工作量也太大了。

                            不過,糟糕的編譯器和文件格式不應(yīng)該阻止我們實(shí)現(xiàn)夢(mèng)想。畢竟,編譯器所做的只是將一些花哨的機(jī)器代碼寫入文件,而文件格式只是一些結(jié)構(gòu),告訴操作系統(tǒng)如何將二進(jìn)制代碼放入內(nèi)存——其實(shí),我們自己就能做到。

                            解決最后一個(gè)問題,程序性能很不錯(cuò)

                            讓我們先用 x86-64 匯編語言編寫一個(gè) IsEven 函數(shù),因?yàn)檫@是我 Intel 處理器驅(qū)動(dòng)的本地語言,它看起來是這樣的:

                            • ; Argument is stored in ECX, return value in EAXXOR EAX, EAX ; Set eax to zero (return value for odd number)CMP ECX, 0h ; Compare arg to 0 JNE 3h ; Skip next two instructions if it wasn't equalINC EAX ; It was even, set even return value (1)RET ; ReturnCMP ECX, 1h ; Compare arg to 1JNE 2 ; Skip next instruction if not equalRET ; Odd return value already in EAX, just RET; add the next 2...2^32-1 comparisons hereRET ; Fallback return

                              這并不是真正正確的匯編代碼,但這不重要,因?yàn)槲覀円謩?dòng)將其編譯成機(jī)器代碼。

                              你問我是怎么做到的?我上網(wǎng)查閱了x86(-64) 體系結(jié)構(gòu)手冊(cè),還利用我早年編寫仿真器和黑客經(jīng)驗(yàn),找出了每條指令的正確操作碼和格式……開個(gè)玩笑,這是不可能的。實(shí)際上,我是直接問 ChatGPT 每條指令的正確操作碼是什么,幸運(yùn)的是,它也沒有產(chǎn)生 x86-64 的任何新擴(kuò)展。

                              所以現(xiàn)在我們只需編寫一個(gè)“編譯器”來輸出這段代碼。請(qǐng)注意,我們將直接使用從 AI 獲取的指令操作碼,下面是用 Python 編寫的代碼:

                              • import struct

                                with open('isEven.bin', 'wb') as file:
                                file.write(b"\x31\xC0") # XOR EAX, EAX

                                for i in range(2**32): ib = struct.pack("<I", i) # Encode i as 32 bit little endian integer

                                file.write(b"\x81\xF9" + ib) # CMP ECX, i

                                if i%2 == 0: file.write(b"\x75\x03") # JNE +3 file.write(b"\xFF\xC0") # INC EAX file.write(b"\xC3") # RET else: file.write(b"\x75\x01") # JNE +1 file.write(b"\xC3") # RET

                                file.write(b"\xC3") # Fallback RET

                                雖然我們?cè)谝欢ǔ潭壬掀x了開頭 TikTok 帖子的最初構(gòu)想,但本質(zhì)并沒有改變:我們創(chuàng)建了一個(gè)非常長的 if 語句列表,用于確定某個(gè)數(shù)字是奇數(shù)還是偶數(shù),并忽略了任何有助于簡(jiǎn)化問題的算術(shù)運(yùn)算。

                                運(yùn)行這個(gè)程序后,我們就得到了一個(gè) 40GB 的文件,其中包含了確定 32 位數(shù)字是偶數(shù)還是奇數(shù)所需的全部 42 億次比較!現(xiàn)在,我們只需編寫能夠加載和使用這些指令的主程序。為了提高性能(這一點(diǎn)非常重要),我決定將文件映射到地址空間,而非一次性讀取全部文件。這樣,我們就可以假裝整個(gè)文件已經(jīng)在內(nèi)存中,讓可憐的操作系統(tǒng)來處理將一個(gè) 40GB 的 Blob 裝入虛擬內(nèi)存的問題。用 READ 和 EXECUTE 權(quán)限映射文件后,我們就可以使用函數(shù)指針調(diào)用代碼了,代碼如下:

                                • #include <stdio.h>#include <Windows.h>#include <stdint.h>

                                  int main(int argc, char* argv[]){ uint32_t number = atoi(argv[1]); // No problems here

                                  // Open code file HANDLE binFile = CreateFileA( "isEven.bin", GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, , OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, );
                                  // Get 64 bit size of file LARGE_INTEGER codeSize; GetFileSizeEx(binFile, &codeSize);

                                  // Create memory map of the file HANDLE mapping = CreateFileMapping( binFile, , PAGE_EXECUTE_READ, 0, 0, );

                                  // Get a pointer to the code LPVOID code = MapViewOfFile( mapping,FILE_MAP_EXECUTE | FILE_MAP_READ, 0, 0, codeSize.QuadPart);

                                  // Create a function that points to the code int (*isEven)(int) = (int(*)(int))code;

                                  if (isEven(number)) printf("even\n"); else printf("odd\n");

                                  CloseHandle(binFile);}

                                  就是這樣!現(xiàn)在我們已經(jīng)具備了判斷任何 32 位(32-bit)數(shù)字是奇是偶的所有功能,讓我們?cè)囈辉嚕?/span>

                                  • PS >.\program.exe 300evenPS >.\program.exe 0evenPS >.\program.exe 1000000evenPS >.\program.exe 100000007oddPS >.\program.exe 400000000evenPS >.\program.exe 400000001oddPS >.\program.exe 400000006evenPS >.\program.exe 4200000000odd <---- WRONG!

                                    差不多了!似乎算法在符號(hào)性方面有問題,任何超過 2^31 的值似乎都會(huì)給出隨機(jī)結(jié)果。那么,讓我們來修復(fù)最后一個(gè)錯(cuò)誤:原來 atoi 不能處理無符號(hào)性,所以它無法解析大數(shù)字。用 strtoul 代替它就能解決所有問題。

                                    uint32_t number = strtoul(argv[1], , 10);// No problems here
                                    • PS >.\program.exe 4200000000evenPS >.\program.exe 4200000001odd

                                      順便提一句,這個(gè)程序的性能很不錯(cuò)。對(duì)于小數(shù)字,結(jié)果能即時(shí)返回,而對(duì)于接近 2^32 極限的大數(shù)字,結(jié)果仍能在大約 10 秒內(nèi)返回。考慮到計(jì)算機(jī)必須從磁盤讀取 40GB 的數(shù)據(jù),將其映射到物理內(nèi)存,然后讓 CPU 在沒有緩存的情況下對(duì)其進(jìn)行處理,老實(shí)說這個(gè)速度已經(jīng)相當(dāng)令人驚嘆了。作為參考,我電腦的配置為 Core i5 12600K,32GB 內(nèi)存,文件存儲(chǔ)在 M.2 SSD 硬盤上。在計(jì)算過程中,我看到 SSD 硬盤的峰值讀取速度約為 800 MB/s。

                                      至此,互聯(lián)網(wǎng)再次被證明是錯(cuò)誤的:你不僅可以按照 TikTok 帖子的方式編寫一個(gè)功能齊全、性能良好的程序,而且還非常有趣。

                                      網(wǎng)友:沒必要,一個(gè)簡(jiǎn)單的 for 循環(huán)就能解決

                                      不過 Andreas Karlsson 的分享,并沒有得到部分開發(fā)者的認(rèn)可,甚至認(rèn)為他有些“嘩眾取寵”:

                                      • “在我看來,這幾乎是過度設(shè)計(jì)。為什么要費(fèi)盡心思生成代碼?只需一個(gè)簡(jiǎn)單的‘for 循環(huán)’就能解決。”

                                      • func isOdd(n int) bool { var odd bool for i := 0; i < n; i++ { odd = !odd } return odd }
                                        • 真正高質(zhì)量的運(yùn)行應(yīng)始終使用遞歸。

                                        • func isOdd(n int) bool { switch { case n == 0: return false case n > 0: return !isOdd(n-1) default: return !isOdd(n+1) } }

                                          還有人指出:“我完全聽不懂這個(gè)笑話。我們從中學(xué)到了什么?exe 文件不能超過4GB?一個(gè)2^32 if 的程序大約是300GB?這看起來并不瘋狂,只是毫無意義。”

                                          對(duì)此,有人反駁道:“可笑的是,他真的做到了。幾十年來,人們一直在拿它開玩笑,但這個(gè)人是認(rèn)真的。由于代碼多得太極端,沒有編譯器可以處理,甚至沒有任何已知的匯編程序,因此他必須生成自己的機(jī)器碼二進(jìn)制文件才能運(yùn)行。結(jié)果最后,他居然還真的成功了。”

                                          參考鏈接:

                                          https://andreasjhkarlsson.github.io/jekyll/update/2023/12/27/4-billion-if-statements.html

                                          https://news.ycombinator.com/item?id=38790597

          錄:

          1. 什么是流程控制語句?
          2. if語句的格式以及使用

          一、什么是流程控制語句

          JavaScript中的語句是從上到下一層一層執(zhí)行的

          通過流程控制語句可以控制程序執(zhí)行的流程,使程序可以根據(jù)一定的條件來選擇執(zhí)行。

          使用條件判斷語句可以在執(zhí)行某個(gè)語句之前進(jìn)行判斷,如果條件成立才會(huì)執(zhí)行語句,如果條件不成立則語句不執(zhí)行。

          二、if語句的格式以及使用

          if 語句,條件位置處,必須Boolean的值 / 表達(dá)式 / 變量,如果不是Boolean類型的話,JS會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換

          格式一:

          if(條件表達(dá)式){
          	條件成立時(shí),執(zhí)行;
          }else{
          	不成立執(zhí)行,這里;
          }

          格式二:

          if(條件表達(dá)式1){
          	條件表達(dá)式1,執(zhí)行;
          }else if(條件表達(dá)式2){
          	條件表達(dá)式2,執(zhí)行;
          }else if(條件表達(dá)式3){
          	條件表達(dá)式3,執(zhí)行;
          }else{
          	表達(dá)式都不成立執(zhí)行,這里;
          }

          規(guī)則:if語句在執(zhí)行時(shí)會(huì)先對(duì)條件表達(dá)式進(jìn)行求值判斷;

          • 如果條件表達(dá)式為true,則執(zhí)行if后的語句;
          • 如果條件表達(dá)式為false,則不會(huì)執(zhí)行if后的語句;

          案例一:

          var age=70
          if(age<60){
           alert("還不到退休的年齡~")
          }else{
           alert("已經(jīng)退休了~")
          }

          案例二:

          var age=40;
          if(age>17) {
           alert("成年了")
          } else if(age>30){
           alert("人到中年")
          }else if(age<18){
           alert("未成年")
          }else{
           alert("年紀(jì)不小了")
          }

          下節(jié)預(yù)告:流程控制語句_switch語句


          主站蜘蛛池模板: 夜夜精品视频一区二区| 一区二区三区在线| 春暖花开亚洲性无区一区二区| 国产成人精品亚洲一区| 无码日韩精品一区二区免费| 成人午夜视频精品一区| 亚洲香蕉久久一区二区三区四区| 人妻少妇一区二区三区| 亚洲一区精品视频在线| 亚洲国产一区二区a毛片| 一本AV高清一区二区三区| 国产一区二区三区不卡在线观看| 亚欧在线精品免费观看一区| 精品少妇一区二区三区在线 | 精品中文字幕一区二区三区四区| 99久久精品午夜一区二区| 亚洲一区二区三区在线| 国产精品分类视频分类一区| 亚洲午夜电影一区二区三区| 熟女少妇精品一区二区| 日韩人妻无码一区二区三区久久99 | 国产综合精品一区二区| 久久精品国产一区二区电影| 国产韩国精品一区二区三区久久| 无码精品人妻一区| 国产色情一区二区三区在线播放| 久久亚洲综合色一区二区三区| 国产亚洲一区二区三区在线| 亚洲香蕉久久一区二区| 精品一区狼人国产在线| 中文字幕在线无码一区二区三区| 国产午夜精品片一区二区三区| 精品国产一区二区三区免费看| 任你躁国产自任一区二区三区| 亚洲欧洲无码一区二区三区| 精品人妻少妇一区二区三区| 亚洲av无码一区二区三区观看| 日本美女一区二区三区| 日韩国产精品无码一区二区三区| 一区二区亚洲精品精华液| 国产亚洲情侣一区二区无|