###やりたい事
0以上で2147483648未満のnを読み取った後に、n 以下の最大の2のべき乗を計算して出力する。
###注意
読み取ったnが0 の時は0を出力。
c
1#include<stdio.h> 2int main(void){ 3 4 5long int n; 6long int b; 7 8scanf("%ld", &n); 9//計算はfor文? 10for(nが2の31乗以下を確認?) 11//どうやってn以下の最大の2のべき乗を毎回確認するのか...? 12... 13 14if(n==0){ 15 k=n; 16 } 17 18printf("%ld\n", b); 19 20return 0; 21}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答8件
0
ベストアンサー
C
1 2#include<stdio.h> 3int main(void) { 4 5 long int n; 6 long int b; 7 int t; 8 9 scanf("%ld", &n); 10 11 t = 0; 12 for ( b = 1L; b*2L <= n; b *= 2L ) { 13 ++t; 14 } 15 printf("2^%d = %ld (< %ld)\n", t, b, n); 16 17 return 0; 18}
投稿2020/04/26 07:00
総合スコア16612
0
long int で扱う, unsigned long int で扱う、
上位側から 1 が立っている最初のビットを探す、下位がわから 1 が立っている最後のビットを探す
の方法の組み合わせの 4つのメソッドを書いてみました。
x.c
c
1#include<stdio.h> 2#include <limits.h> 3#include <stdlib.h> 4 5long int get_largest_2pow_0(long int n) { 6 if (n == 0) { 7 return 0; 8 } 9 long int ans = 1; 10 while (ans > 0 && ans <= n) { 11 ans = ans << 1; 12 } 13 return labs(ans / 2); 14} 15 16 17long int get_largest_2pow_1(long int n) { 18 if (n == 0) { 19 return 0; 20 } 21 long int ans = -1; 22 while (ans & n) { 23 ans = ans << 1; 24 } 25 return -(ans >> 1); 26} 27 28long int get_largest_2pow_u0(unsigned long int n) { 29 unsigned long int ans = 1L; 30 while (ans <= n) { 31 ans = ans << 1; 32 } 33 return ans >> 1; 34} 35 36long int get_largest_2pow_u1(unsigned long int n) { 37 if (n == 0) { 38 return 0; 39 } 40 unsigned long int ans = ~0; 41 while (ans & n) { 42 ans = ans << 1; 43 } 44 return (~ans >> 1) + 1; 45} 46 47int main(void) { 48 long int data[] = { 49 // -1, 50 0, 51 1, 2, 3, 4, 5, 7, 8, 9, 52 (1 << 7) - 1, 1 << 7 , (1 << 7) + 1, 53 (1 << 15) - 1, 1 << 15, (1 << 15) + 1, 54 2147483646, 2147483647, 55 LONG_MAX - 1, LONG_MAX 56 }; 57 58 for(int i = 0; i < sizeof(data) / sizeof(long int); i++) { 59 long int num = data[i]; 60 printf("%ld -> %ld, %ld, %ld, %ld\n", 61 num, 62 get_largest_2pow_0(num), get_largest_2pow_1(num), 63 get_largest_2pow_u0(num), get_largest_2pow_u1(num)); 64 } 65 return 0; 66}
実行例:
このコードでは いずれも 順番にビットをしらべています。
(0x1, 0x10, ... 0x10000000) のテーブルを用意して、2分法で 最上位のビット1を探すという方法もありかもしれません。(数をあてるHight & low ゲームみたいに)
でも ビット演算にはとんでもないテクニックがいろいろあります。
質問文の問題は 左からビットみていったとき 最初に 1 が現れる位置をもとめることと同じです。
興味があれば、こういった方法も研究してみるとう良いです。下の参考情報ページなどを読んでみてください。
参考情報
- データ型の最大値と最小値の一覧【32/64bit環境 limits.h/stdint.h】
https://marycore.jp/prog/c-lang/data-type-min-max-values/
- ビット演算あれこれ
http://marupeke296.com/TIPS_No17_Bit.html
- de Bruijn sequenceを用いたLSB/MSB位置検出テクニック
https://onihusube.hatenablog.com/entry/2019/09/20/230416
- ++11で実装するNTZとNLZ
投稿2020/04/26 22:22
総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
C
1#include <stdio.h> 2#include <stdint.h> 3#include <inttypes.h> 4 5int main(void) 6{ 7 uint_fast32_t n; 8 if (scanf("%" SCNuFAST32, &n) != 1 || n >= (1ul<<31)) return 1; 9 uint_fast32_t x = 1; 10 while (x <= n) x *= 2; 11 printf("%" PRIuFAST32 "\n", x / 2); 12 return 0; 13}
投稿2020/04/26 07:18
総合スコア21739
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/26 09:46 編集
0
解決済みですが、再帰関数で書いてみました。動作未確認。
C
1unsigned int largetstPowerOf2(unsigned int n) 2{ 3 //nがゼロの場合は答えが存在しないので、nは1以上とします。 4 return (1 == n) ? 1 : largestPowerOf2(n >> 1) << 1; 5}
投稿2020/05/03 12:14
編集2020/05/03 12:20総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
C
1#include <stdio.h> 2 3int main(void) 4{ 5 int n; 6 scanf("%d", &n); 7 n |= (n >> 1); 8 n |= (n >> 2); 9 n |= (n >> 4); 10 n |= (n >> 8); 11 n |= (n >>16); 12 n -= (n >> 1); 13 printf("%d\n", n); 14}
別解
C
1#include <stdio.h> 2 3int main(void) 4{ 5 int n; 6 scanf("%d", &n); 7 while (n & n-1) n &= n-1; 8 printf("%d\n", n); 9}
投稿2020/04/26 17:29
編集2020/04/26 19:23総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
C
1#include <stdio.h> 2#include <inttypes.h> 3int main(void){ 4 5 6 uint32_t n; 7 uint32_t b; 8 9 scanf("%"PRId32, &n); 10 b=n; 11 b = (b & 0xFFFF0000) ? (b & 0xFFFF0000) : b; 12 b = (b & 0xFF00FF00) ? (b & 0xFF00FF00) : b; 13 b = (b & 0xF0F0F0F0) ? (b & 0xF0F0F0F0) : b; 14 b = (b & 0xCCCCCCCC) ? (b & 0xCCCCCCCC) : b; 15 b = (b & 0xAAAAAAAA) ? (b & 0xAAAAAAAA) : b; 16 17 18 printf("%"PRId32"\n", b); 19 20 return 0; 21}
投稿2020/04/26 07:29
総合スコア13553
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/26 07:28
2020/04/26 07:44
2020/04/27 05:35 編集
2020/05/03 12:07